1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21#pragma once
22
23// LOVE
24#include "common/Data.h"
25#include "common/StringMap.h"
26#include "common/int.h"
27#include "common/pixelformat.h"
28#include "common/floattypes.h"
29#include "common/Color.h"
30#include "filesystem/FileData.h"
31#include "thread/threads.h"
32#include "ImageDataBase.h"
33#include "FormatHandler.h"
34
35using love::thread::Mutex;
36
37namespace love
38{
39namespace image
40{
41
42/**
43 * Represents raw pixel data.
44 **/
45class ImageData : public ImageDataBase
46{
47public:
48
49 union Pixel
50 {
51 uint8 rgba8[4];
52 uint16 rgba16[4];
53 float16 rgba16f[4];
54 float rgba32f[4];
55 uint16 packed16;
56 uint32 packed32;
57 };
58
59 typedef void (*PixelSetFunction)(const Colorf &c, Pixel *p);
60 typedef void (*PixelGetFunction)(const Pixel *p, Colorf &c);
61
62 static love::Type type;
63
64 ImageData(Data *data);
65 ImageData(int width, int height, PixelFormat format = PIXELFORMAT_RGBA8);
66 ImageData(int width, int height, PixelFormat format, void *data, bool own);
67 ImageData(const ImageData &c);
68 virtual ~ImageData();
69
70 /**
71 * Paste part of one ImageData onto another. The subregion defined by the top-left
72 * corner (sx, sy) and the size (sw,sh) will be pasted to (dx,dy) in this ImageData.
73 * @param dx The destination x-coordinate.
74 * @param dy The destination y-coordinate.
75 * @param sx The source x-coordinate.
76 * @param sy The source y-coordinate.
77 * @param sw The source width.
78 * @param sh The source height.
79 **/
80 void paste(ImageData *src, int dx, int dy, int sx, int sy, int sw, int sh);
81
82 /**
83 * Checks whether a position is inside this ImageData. Useful for checking bounds.
84 * @param x The position along the x-axis.
85 * @param y The position along the y-axis.
86 **/
87 bool inside(int x, int y) const;
88
89 /**
90 * Sets the pixel at location (x,y).
91 * @param x The location along the x-axis.
92 * @param y The location along the y-axis.
93 * @param p The color to use for the given location.
94 **/
95 void setPixel(int x, int y, const Colorf &p);
96
97 /**
98 * Gets the pixel at location (x,y).
99 * @param x The location along the x-axis.
100 * @param y The location along the y-axis.
101 * @return The color for the given location.
102 **/
103 void getPixel(int x, int y, Colorf &c) const;
104 Colorf getPixel(int x, int y) const;
105
106 /**
107 * Encodes raw pixel data into a given format.
108 * @param f The file to save the encoded image data to.
109 * @param format The format of the encoded data.
110 **/
111 love::filesystem::FileData *encode(FormatHandler::EncodedFormat format, const char *filename, bool writefile) const;
112
113 love::thread::Mutex *getMutex() const;
114
115 // Implements ImageDataBase.
116 ImageData *clone() const override;
117 void *getData() const override;
118 size_t getSize() const override;
119 bool isSRGB() const override;
120
121 size_t getPixelSize() const;
122
123 PixelSetFunction getPixelSetFunction() const { return pixelSetFunction; }
124 PixelGetFunction getPixelGetFunction() const { return pixelGetFunction; }
125
126 static bool validPixelFormat(PixelFormat format);
127 static bool canPaste(PixelFormat src, PixelFormat dst);
128
129 static PixelSetFunction getPixelSetFunction(PixelFormat format);
130 static PixelGetFunction getPixelGetFunction(PixelFormat format);
131
132 static bool getConstant(const char *in, FormatHandler::EncodedFormat &out);
133 static bool getConstant(FormatHandler::EncodedFormat in, const char *&out);
134 static std::vector<std::string> getConstants(FormatHandler::EncodedFormat);
135
136private:
137
138 // Create imagedata. Initialize with data if not null.
139 void create(int width, int height, PixelFormat format, void *data = nullptr);
140
141 // Decode and load an encoded format.
142 void decode(Data *data);
143
144 // The actual data.
145 unsigned char *data = nullptr;
146
147 love::thread::MutexRef mutex;
148
149 // The format handler that was used to decode the ImageData. We need to know
150 // this so we can properly delete memory allocated by the decoder.
151 StrongRef<FormatHandler> decodeHandler;
152
153 PixelSetFunction pixelSetFunction;
154 PixelGetFunction pixelGetFunction;
155
156 static StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM>::Entry encodedFormatEntries[];
157 static StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM> encodedFormats;
158
159}; // ImageData
160
161} // image
162} // love
163