1 | // tImageICO.h  |
2 | //  |
3 | // This class knows how to load windows icon (ico) files. It loads the data into multiple tPixel arrays, one for each  |
4 | // frame (ico files may be multiple images at different resolutions). These arrays may be 'stolen' by tPictures. The  |
5 | // loading code is a modificaton of code from Victor Laskin. In particular the code now:  |
6 | // a) Loads all frames of an ico, not just the biggest one.  |
7 | // b) Supports embedded png images.  |
8 | // c) Supports widths and heights of 256.  |
9 | // Victor Laskin's header/licence in the original ico.cpp is shown below.  |
10 | //  |
11 | // Copyright (c) 2020 Tristan Grimmer.  |
12 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby  |
13 | // granted, provided that the above copyright notice and this permission notice appear in all copies.  |
14 | //  |
15 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL  |
16 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,  |
17 | // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN  |
18 | // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR  |
19 | // PERFORMANCE OF THIS SOFTWARE.  |
20 | //  |
21 | // Includes modified version of code from Victor Laskin.  |
22 | // Code by Victor Laskin (victor.laskin@gmail.com)  |
23 | // Rev 2 - 1bit color was added, fixes for bit mask.  |
24 | //  |
25 | // THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED  |
26 | // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL  |
27 | // THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  |
28 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  |
29 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  |
30 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  |
31 | // POSSIBILITY OF SUCH DAMAGE.  |
32 |   |
33 | #pragma once  |
34 | #include <Foundation/tString.h>  |
35 | #include <Math/tColour.h>  |
36 | #include <Image/tPixelFormat.h>  |
37 | namespace tImage  |
38 | {  |
39 |   |
40 |   |
41 | class tImageICO  |
42 | {  |
43 | public:  |
44 | // Creates an invalid tImageICO. You must call Load manually.  |
45 | tImageICO() { }  |
46 | tImageICO(const tString& icoFile) { Load(icoFile); }  |
47 |   |
48 | virtual ~tImageICO() { Clear(); }  |
49 |   |
50 | // Clears the current tImageICO before loading. If false returned object is invalid.  |
51 | bool Load(const tString& icoFile);  |
52 |   |
53 | // After this call no memory will be consumed by the object and it will be invalid.  |
54 | void Clear();  |
55 | bool IsValid() const { return (GetNumFrames() >= 1); }  |
56 | int GetNumFrames() const { return Frames.GetNumItems(); }  |
57 | tPixelFormat GetBestSrcPixelFormat() const;  |
58 |   |
59 | struct Frame : public tLink<Frame>  |
60 | {  |
61 | int Width = 0;  |
62 | int Height = 0;  |
63 | tPixel* Pixels = nullptr;  |
64 | tPixelFormat SrcPixelFormat = tPixelFormat::Invalid;  |
65 | };  |
66 |   |
67 | // After this call you are the owner of the frame and must eventually delete it. The frame you stole will no  |
68 | // longer be a valid frame of the tImageICO, but the remaining ones will still be valid.  |
69 | Frame* StealFrame(int );  |
70 | Frame* GetFrame(int );  |
71 |   |
72 | private:  |
73 | bool PopulateFrames(const uint8* buffer, int numBytes);   |
74 | Frame* CreateFrame(const uint8* buffer, int width, int height, int numBytes);  |
75 |   |
76 | tList<Frame> Frames;  |
77 | };  |
78 |   |
79 |   |
80 | // Implementation only below.  |
81 |   |
82 |   |
83 | inline tImageICO::Frame* tImage::tImageICO::StealFrame(int )  |
84 | {  |
85 | Frame* p = GetFrame(frameNum);  |
86 | if (!p)  |
87 | return nullptr;  |
88 |   |
89 | return Frames.Remove(p);  |
90 | }  |
91 |   |
92 |   |
93 | inline tImageICO::Frame* tImage::tImageICO::GetFrame(int )  |
94 | {  |
95 | if ((frameNum >= Frames.GetNumItems()) || (frameNum < 0))  |
96 | return nullptr;  |
97 |   |
98 | Frame* f = Frames.First();  |
99 | while (frameNum--)  |
100 | f = f->Next();  |
101 |   |
102 | return f;  |
103 | }  |
104 |   |
105 |   |
106 | inline void tImageICO::Clear()  |
107 | {  |
108 | while (Frame* frame = Frames.Remove())  |
109 | {  |
110 | delete[] frame->Pixels;  |
111 | delete frame;  |
112 | }  |
113 | }  |
114 |   |
115 |   |
116 | inline tPixelFormat tImageICO::GetBestSrcPixelFormat() const  |
117 | {  |
118 | tPixelFormat bestFormat = tPixelFormat::Invalid;  |
119 | for (Frame* frame = Frames.First(); frame; frame = frame->Next())  |
120 | {  |
121 | if (frame->SrcPixelFormat == tPixelFormat::Invalid)  |
122 | continue;  |
123 | if (frame->SrcPixelFormat == tPixelFormat::R8G8B8A8)  |
124 | return tPixelFormat::R8G8B8A8;  |
125 | else if (frame->SrcPixelFormat < bestFormat)  |
126 | bestFormat = frame->SrcPixelFormat;  |
127 | }  |
128 |   |
129 | return bestFormat;  |
130 | }  |
131 |   |
132 |   |
133 | }  |
134 | |