1 | // tImageTGA.h  |
2 | //  |
3 | // This class knows how to load and save targa (.tga) files into tPixel arrays. These tPixels may be 'stolen' by the  |
4 | // tPicture's constructor if a targa file is specified. After the array is stolen the tImageTGA is invalid. This is  |
5 | // purely for performance.  |
6 | //  |
7 | // Copyright (c) 2006, 2017, 2019, 2020 Tristan Grimmer.  |
8 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby  |
9 | // granted, provided that the above copyright notice and this permission notice appear in all copies.  |
10 | //  |
11 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL  |
12 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,  |
13 | // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN  |
14 | // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR  |
15 | // PERFORMANCE OF THIS SOFTWARE.  |
16 |   |
17 | #pragma once  |
18 | #include <Foundation/tString.h>  |
19 | #include <Math/tColour.h>  |
20 | #include <Image/tPixelFormat.h>  |
21 | namespace tImage  |
22 | {  |
23 |   |
24 |   |
25 | class tImageTGA  |
26 | {  |
27 | public:  |
28 | // Creates an invalid tImageTGA. You must call Load manually.  |
29 | tImageTGA() { }  |
30 | tImageTGA(const tString& tgaFile) { Load(tgaFile); }  |
31 |   |
32 | // The data is copied out of tgaFileInMemory. Go ahead and delete after if you want.  |
33 | tImageTGA(const uint8* tgaFileInMemory, int numBytes) { Set(tgaFileInMemory, numBytes); }  |
34 |   |
35 | // This one sets from a supplied pixel array. If steal is true it takes ownership of the pixels pointer. Otherwise  |
36 | // it just copies the data out.  |
37 | tImageTGA(tPixel* pixels, int width, int height, bool steal = false) { Set(pixels, width, height, steal); }  |
38 |   |
39 | virtual ~tImageTGA() { Clear(); }  |
40 |   |
41 | // Clears the current tImageTGA before loading. 16, 24, or 32 bit targas can be loaded. The tga may be uncompressed  |
42 | // or RLE compressed. Other compression methods are rare and unsupported. Returns success. If false returned,  |
43 | // object is invalid.  |
44 | bool Load(const tString& tgaFile);  |
45 | bool Set(const uint8* tgaFileInMemory, int numBytes);  |
46 |   |
47 | // This one sets from a supplied pixel array. If steal is true it takes ownership of the pixels pointer. Otherwise  |
48 | // it just copies the data out.  |
49 | bool Set(tPixel* pixels, int width, int height, bool steal = false);  |
50 |   |
51 | enum class tFormat  |
52 | {  |
53 | Invalid, // Invalid must be 0.  |
54 | Auto, // Save function will decide format. Bit24 if all image pixels are opaque and Bit32 otherwise.  |
55 | Bit24, // 24 bit colour.  |
56 | Bit32 // 24 bit colour with 8 bits opacity in the alpha channel.  |
57 | };  |
58 | enum class tCompression  |
59 | {  |
60 | None, // No compression.  |
61 | RLE // Run Length Encoding.  |
62 | };  |
63 |   |
64 | // Saves the tImageTGA to the Targa file specified. The extension of filename must be ".tga". If tFormat is Auto,  |
65 | // this function will decide the format. Bit24 if all image pixels are opaque and Bit32 otherwise. Returns the format  |
66 | // that the file was saved in, or tFormat::Invalid if there was a problem. Since Invalid is 0, you can use an 'if'.  |
67 | tFormat Save(const tString& tgaFile, tFormat = tFormat::Auto, tCompression = tCompression::RLE) const;  |
68 |   |
69 | // After this call no memory will be consumed by the object and it will be invalid.  |
70 | void Clear();  |
71 | bool IsValid() const { return Pixels ? true : false; }  |
72 |   |
73 | int GetWidth() const { return Width; }  |
74 | int GetHeight() const { return Height; }  |
75 |   |
76 | // All pixels must be opaque (alpha = 1) for this to return true.  |
77 | bool IsOpaque() const;  |
78 |   |
79 | // After this call you are the owner of the pixels and must eventually delete[] them. This tImageTGA object is  |
80 | // invalid afterwards.  |
81 | tPixel* StealPixels();  |
82 | tPixel* GetPixels() const { return Pixels; }  |
83 | tPixelFormat SrcPixelFormat = tPixelFormat::Invalid;  |
84 |   |
85 | private:  |
86 | bool SaveUncompressed(const tString& tgaFile, tFormat) const;  |
87 | bool SaveCompressed(const tString& tgaFile, tFormat) const;  |
88 | void ReadColourBytes(tColouri& dest, const uint8* src, int bitDepth);  |
89 |   |
90 | // So this is a neat C++11 feature. Allows simplified constructors.  |
91 | int Width = 0;  |
92 | int Height = 0;  |
93 | tPixel* Pixels = nullptr;  |
94 | };  |
95 |   |
96 |   |
97 | // Implementation below this line.  |
98 |   |
99 |   |
100 | inline void tImageTGA::Clear()  |
101 | {  |
102 | Width = 0;  |
103 | Height = 0;  |
104 | delete[] Pixels;  |
105 | Pixels = nullptr;  |
106 | SrcPixelFormat = tPixelFormat::Invalid;  |
107 | }  |
108 |   |
109 |   |
110 | }  |
111 |   |
112 |   |
113 |   |
114 | |