1// tBaseImage.h 
2// 
3// Abstract base class for all tImageTYPE classes that load and save to a specific format. 
4// 
5// Copyright (c) 2022, 2024 Tristan Grimmer. 
6// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
7// granted, provided that the above copyright notice and this permission notice appear in all copies. 
8// 
9// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
10// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
11// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
12// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
13// PERFORMANCE OF THIS SOFTWARE. 
14 
15#pragma once 
16#include <Foundation/tString.h> 
17#include <Math/tColour.h> 
18#include <Image/tPixelFormat.h> 
19#include "Image/tFrame.h" 
20namespace tImage 
21
22class tPicture
23class tLayer
24 
25 
26// These are hany for all image types that may contain cubemaps. 
27enum tFaceIndex : uint32 
28
29 tFaceIndex_Default
30 tFaceIndex_PosX = tFaceIndex_Default
31 tFaceIndex_NegX
32 tFaceIndex_PosY
33 tFaceIndex_NegY
34 tFaceIndex_PosZ
35 tFaceIndex_NegZ
36 tFaceIndex_NumFaces 
37}; 
38 
39// Faces are always specified using a left-handed coord system even when using the OpenGL functions. 
40enum tFaceFlag : uint32 
41
42 tFaceFlag_PosX = 1 << tFaceIndex_PosX
43 tFaceFlag_NegX = 1 << tFaceIndex_NegX
44 tFaceFlag_PosY = 1 << tFaceIndex_PosY
45 tFaceFlag_NegY = 1 << tFaceIndex_NegY
46 tFaceFlag_PosZ = 1 << tFaceIndex_PosZ
47 tFaceFlag_NegZ = 1 << tFaceIndex_NegZ
48 tFaceFlag_All = 0xFFFFFFFF 
49}; 
50 
51 
52// Abstract base class for all tImage types. At a minumum all tImageEXTs need to be able to be set from a single tFrame 
53// and return a single tFrame. 
54class tBaseImage 
55
56public
57 virtual ~tBaseImage() { } 
58 
59 // This one sets from a supplied pixel array. If steal is true it takes ownership of the pixels pointer. Otherwise 
60 // it just copies the data out. 
61 virtual bool Set(tPixel4b* pixels, int width, int height, bool steal = false) = 0
62 
63 // For multi-frame image types (say an animated webp), the first frame is chosen. The 'steal' bool tells the object 
64 // whether it is allowed to take ownership of the supplied frame, or whether it must copy the data out of it. 
65 // Returns true on success. Image will be invalid if false returned. If steal true, entire frame object is stolen. 
66 virtual bool Set(tFrame*, bool steal = true) = 0
67 
68 // Similar to above but sets from a tPicture. If steal is true, it takes the pixels from the picture and leaves it 
69 // in an invalid state. 
70 virtual bool Set(tPicture& picture, bool steal = true) = 0
71 
72 // For some formats (eg. .astc, .dds, .ktx) the internal representation may not be R8G8B8A8 unless a decode was 
73 // performed (which is optional). In these cases a new frame will be generated if the decode was performed, and 
74 // nullptr otherwise. 
75 // 
76 // Stealing a frame (the default) may or may-not invalidate an image. For multiframe image types, if there is more 
77 // than one frame, stealing just takes one away. Only if it was the last one, will it invalidate the object. In all 
78 // cases if steal is false, you are guaranteed the tImage is not modified. A new frame is created for you if 
79 // possible (again it won't force a decode for, say, ktx2 files). 
80 virtual tFrame* GetFrame(bool steal = true) = 0
81 
82 // After this call no memory will be consumed by the object and it will be invalid. The base version here can be 
83 // used just to clear the members in the base class. 
84 virtual void Clear() { PixelFormatSrc = tPixelFormat::Unspecified; PixelFormat = tPixelFormat::Unspecified; ColourProfileSrc = tColourProfile::Unspecified; ColourProfile = tColourProfile::Unspecified; } 
85 
86 virtual bool IsValid() const = 0
87 
88 // Returns the original (source) pixel format of the image. The source may be a file, or a buffer in memory, or some 
89 // other object like a picture. This format is only modified if you reload or set an image from new data. Saving to 
90 // a file does not modify this. 
91 virtual tPixelFormat GetPixelFormatSrc() const { return PixelFormatSrc; } 
92 
93 // Returns the current in-memory pixel format of this image object. Load paramters often modify it from the source 
94 // pixel format. For example, if you load a DDS and decide to decode, this format will return the decoded format, 
95 // often R8G8B8A8. If you decide not to decode, it will match the source format. Another example is loading a 
96 // RLE-compressed TGA, it also gets uncompressed to R8G8B8A8. Some tImage classes like tImagePNG support decodeing 
97 // to R16G16B16A16, and in the future some might support R32G32B32A32f for the decompressed/generic HDR format. 
98 virtual tPixelFormat GetPixelFormat() const { return PixelFormat; } 
99 
100 // Returns the original (source) colour profile of the image. See comment for GetPixelFormatSrc. It is worth noting 
101 // that many image types do not store colour-space information at all, in which case the ColourProfile members will 
102 // remain unspecified. 
103 virtual tColourProfile GetColourProfileSrc() const { return ColourProfileSrc; } 
104 
105 // Returns the current colour profile of the pixels in this image object. Load paramters often modify it from the 
106 // source profile. For example loading a linear-colour-space HDR file will likely decode it into sRGB for display 
107 // purposes (if you asked it to do so with load parameters). 
108 virtual tColourProfile GetColourProfile() const { return ColourProfile; } 
109 
110 virtual tAlphaMode GetAlphaMode() const { return tAlphaMode::Unspecified; } 
111 virtual tChannelType GetChannelType() const { return tChannelType::Unspecified; } 
112 
113 // Not all derived classes need to support these next four functions. 
114 virtual bool IsMipmapped() const { return false; } 
115 virtual bool IsCubemap() const { return false; } 
116 
117 // Gets the layers but you're not allowed to delete them, they're not yours. Make sure the list you supply doesn't 
118 // delete them when it's destructed. Returns the number of items appended to the list. 
119 virtual int GetLayers(tList<tLayer>&) const { return 0; } 
120 virtual int GetCubemapLayers(tList<tLayer> layers[tFaceIndex_NumFaces], uint32 faceFlags = tFaceFlag_All) const { return 0; } 
121 
122protected
123 // Pretty sure all tImageXXX classes will find these useful. 
124 tPixelFormat PixelFormatSrc = tPixelFormat::Unspecified
125 tPixelFormat PixelFormat = tPixelFormat::Unspecified
126 tColourProfile ColourProfileSrc = tColourProfile::Unspecified
127 tColourProfile ColourProfile = tColourProfile::Unspecified
128}; 
129 
130 
131
132