1// tLayer.cpp 
2// 
3// A tLayer is a data container for texture pixel data. It is used only by the tTexture class to store image data. It 
4// contains data that may be in a variety of hardware-ready formats, like dxt5. It is primarily used to store the 
5// multiple mipmap layers of a texture. Main members are width, height, pixel format, and a function to compute data 
6// size based on those three variables. It knows how to save and load itself in tChunk format. 
7// 
8// tLayers may have any width and height in [1, MaxLayerDimension]. If the pixel format is block-based (4x4 pixels) 
9// the tLayer still allows smaller than 4 width and height. However, a whole block is still needed so the number of 
10// bytes will be the block size for the particular BC format. For example, a 1x1 BC1 format layer still needs 8 bytes. 
11// A 5x5 BC format layer would need 4 blocks (same as an 8x8). The tLayer does not place further constraints on width 
12// and height. A higher level system, for example, may want to ensure power-of-two sizes, or multiple of 4, but that 
13// shouldn't and doesn't happen here. 
14// 
15// Copyright (c) 2006, 2017 Tristan Grimmer. 
16// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
17// granted, provided that the above copyright notice and this permission notice appear in all copies. 
18// 
19// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
21// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
22// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
23// PERFORMANCE OF THIS SOFTWARE. 
24 
25#include "Image/tLayer.h" 
26using namespace tImage
27 
28 
29bool tLayer::IsOpaqueFormat() const 
30
31 // We assume that if the layer is using a format that supports transparency that there are, in fact, transparent 
32 // pixels present. It won't hurt if there aren't, but it would be rendered with blending on if the material was 
33 // opaque and might be a bit slower. 
34 switch (PixelFormat
35
36 case tPixelFormat::R8G8B8A8
37 case tPixelFormat::B8G8R8A8
38 case tPixelFormat::BC1_DXT1BA
39 case tPixelFormat::BC2_DXT3
40 case tPixelFormat::BC3_DXT5
41 case tPixelFormat::G3B5A1R5G2
42 case tPixelFormat::G4B4A4R4
43 case tPixelFormat::L8A8
44 return false
45 
46 default
47 return true
48
49 
50 return true
51
52 
53 
54bool tLayer::operator==(const tLayer& src) const 
55
56 if (!IsValid() || !src.IsValid()) 
57 return false
58 
59 if (PixelFormat != src.PixelFormat
60 return false
61 
62 if ((Width != src.Width) || (Height != src.Height)) 
63 return false
64 
65 int dataSize = GetDataSize(); 
66 return tStd::tMemcmp(Data, src.Data, dataSize) ? false : true
67
68 
69 
70void tLayer::Save(tChunkWriter& chunk) const 
71
72 chunk.Begin(tChunkID::Image_Layer); 
73
74 // This chunk must be saved first. 
75 chunk.Begin(tChunkID::Image_LayerProperties); 
76
77 chunk.Write(PixelFormat); 
78 chunk.Write(Width); 
79 chunk.Write(Height); 
80
81 chunk.End(); 
82 
83 chunk.Begin(tChunkID::Image_LayerData); 
84
85 int dataSize = GetDataSize(); 
86 chunk.Write(Data, dataSize); 
87
88 chunk.End(); 
89
90 chunk.End(); 
91
92 
93 
94void tLayer::Load(const tChunk& chunk, bool ownsData
95
96 Clear(); 
97 if (chunk.ID() != tChunkID::Image_Layer
98 return
99 
100 OwnsData = ownsData
101 for (tChunk ch = chunk.First(); ch.IsValid(); ch = ch.Next()) 
102
103 switch (ch.ID()) 
104
105 // This chunk must be loaded first. 
106 case tChunkID::Image_LayerProperties
107
108 ch.GetItem(PixelFormat); 
109 ch.GetItem(Width); 
110 ch.GetItem(Height); 
111 break
112
113 
114 case tChunkID::Image_LayerData
115
116 int dataSize = GetDataSize(); 
117 if (dataSize <= 0
118 return
119 
120 tAssert(!Data); 
121 if (OwnsData
122
123 Data = new uint8[dataSize]; 
124 tStd::tMemcpy(Data, ch.Data(), dataSize); 
125
126 else 
127
128 Data = (uint8*)ch.Data(); 
129
130 break
131
132
133
134
135