1// tImageBMP.h 
2// 
3// This class knows how to load and save windows bitmap (.bmp) 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 tImageBMP is invalid. This is 
5// purely for performance. 
6// 
7// The code in this module is a modification of code from https://github.com/phm97/bmp under the BSD 2-Clause License: 
8// 
9// Copyright (c) 2019, phm97 
10// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
11// following conditions are met: 
12// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following 
13// disclaimer. 
14// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 
15// following disclaimer in the documentation and/or other materials provided with the distribution. 
16// 
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
18// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
21// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
22// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24// 
25// The modifications to use Tacent datatypes and conversion to C++ are under the ISC licence: 
26// 
27// Copyright (c) 2020 Tristan Grimmer. 
28// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
29// granted, provided that the above copyright notice and this permission notice appear in all copies. 
30// 
31// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
32// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
33// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
34// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
35// PERFORMANCE OF THIS SOFTWARE. 
36 
37#pragma once 
38#include <Foundation/tString.h> 
39#include <Math/tColour.h> 
40#include <Image/tPixelFormat.h> 
41namespace tImage 
42
43 
44 
45class tImageBMP 
46
47public
48 // Creates an invalid tImageBMP. You must call Load manually. 
49 tImageBMP() { } 
50 tImageBMP(const tString& bmpFile) { Load(bmpFile); } 
51 
52 // This one sets from a supplied pixel array. If steal is true it takes ownership of the pixels pointer. Otherwise 
53 // it just copies the data out. 
54 tImageBMP(tPixel* pixels, int width, int height, bool steal = false) { Set(pixels, width, height, steal); } 
55 
56 virtual ~tImageBMP() { Clear(); } 
57 
58 // Clears the current tImageBMP before loading. Supports RGBA, RGB, R5G5B5A1, 8-bit indexed, 4-bit indexed, 1-bit 
59 // indexed, and run-length encoded RLE4 and RLE8. Returns success. If false returned, object is invalid. 
60 bool Load(const tString& bmpFile); 
61 
62 // This one sets from a supplied pixel array. If steal is true it takes ownership of the pixels pointer. Otherwise 
63 // it just copies the data out. 
64 bool Set(tPixel* pixels, int width, int height, bool steal = false); 
65 
66 enum class tFormat 
67
68 Invalid, // Invalid must be 0. 
69 Auto, // Save function will decide format. Bit24 if all image pixels are opaque and Bit32 otherwise. 
70 BPP24, // RGB. 24 bit colour. 
71 BPP32 // RGBA. 24 bit colour and 8 bits opacity in the alpha channel. 
72 }; 
73 
74 // Saves the tImageBMP to the bmp file specified. The extension must be ".bmp". If tFormat is Auto, this function 
75 // will decide the format. BPP24 if all image pixels are opaque and BPP32 otherwise. Returns the format that the 
76 // file was saved in, or tFormat::Invalid if there was a problem. Since Invalid is 0, you can use an 'if'. 
77 tFormat Save(const tString& bmpFile, tFormat = tFormat::Auto) const
78 
79 // After this call no memory will be consumed by the object and it will be invalid. 
80 void Clear(); 
81 bool IsValid() const { return Pixels ? true : false; } 
82 
83 int GetWidth() const { return Width; } 
84 int GetHeight() const { return Height; } 
85 
86 // All pixels must be opaque (alpha = 1) for this to return true. 
87 bool IsOpaque() const
88 
89 // After this call you are the owner of the pixels and must eventually delete[] them. This tImageBMP object is 
90 // invalid afterwards. 
91 tPixel* StealPixels(); 
92 tPixel* GetPixels() const { return Pixels; } 
93 tPixelFormat SrcPixelFormat = tPixelFormat::Invalid
94 
95private
96 const uint16 FourCC = 0x4D42
97 
98 #pragma pack(push, r1, 1) 
99 struct Header 
100
101 uint16 FourCC
102 int32 Size
103 int32 AppId
104 int32 Offset
105 }; 
106 
107 struct InfoHeader 
108
109 int32 HeaderSize
110 int32 Width
111 int32 Height
112 int16 NumPlanes
113 int16 BPP
114 int32 Compression
115 int32 ImageSize
116 int32 HorizontalResolution
117 int32 VerticalResolution
118 int32 ColoursUsed
119 int32 ColoursImportant
120 }; 
121 
122 struct PaletteColour 
123
124 uint8 B
125 uint8 G
126 uint8 R
127 uint8 A
128 }; 
129 #pragma pack(pop, r1) 
130 
131 void ReadRow_Pixels32 (tFileHandle, uint8* dest); 
132 void ReadRow_Pixels24 (tFileHandle, uint8* dest); 
133 void ReadRow_Pixels16 (tFileHandle, uint8* dest); 
134 void ReadRow_Indexed8 (tFileHandle, uint8* dest, PaletteColour* palette); 
135 void ReadRow_Indexed4 (tFileHandle, uint8* dest, PaletteColour* palette); 
136 void ReadRow_Indexed1 (tFileHandle, uint8* dest, PaletteColour* palette); 
137 void ReadRow_IndexedRLE8(tFileHandle, uint8* dest, PaletteColour* palette); 
138 void ReadRow_IndexedRLE4(tFileHandle, uint8* dest, PaletteColour* palette); 
139 
140 // So this is a neat C++11 feature. Allows simplified constructors. 
141 int Width = 0
142 int Height = 0
143 tPixel* Pixels = nullptr
144}; 
145 
146 
147// Implementation below this line. 
148 
149 
150inline void tImageBMP::Clear() 
151
152 Width = 0
153 Height = 0
154 delete[] Pixels
155 Pixels = nullptr
156 SrcPixelFormat = tPixelFormat::Invalid
157
158 
159 
160
161