| 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, 2022 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"  |
| 26 | using namespace tImage;  |
| 27 |   |
| 28 |   |
| 29 | bool tLayer::operator==(const tLayer& src) const  |
| 30 | {  |
| 31 | if (!IsValid() || !src.IsValid())  |
| 32 | return false;  |
| 33 |   |
| 34 | if (PixelFormat != src.PixelFormat)  |
| 35 | return false;  |
| 36 |   |
| 37 | if ((Width != src.Width) || (Height != src.Height))  |
| 38 | return false;  |
| 39 |   |
| 40 | int dataSize = GetDataSize();  |
| 41 | return tStd::tMemcmp(a: Data, b: src.Data, numBytes: dataSize) ? false : true;  |
| 42 | }  |
| 43 |   |
| 44 |   |
| 45 | void tLayer::Save(tChunkWriter& chunk) const  |
| 46 | {  |
| 47 | chunk.Begin(chunkID: tChunkID::Image_Layer);  |
| 48 | {  |
| 49 | // This chunk must be saved first.  |
| 50 | chunk.Begin(chunkID: tChunkID::Image_LayerProperties);  |
| 51 | {  |
| 52 | chunk.Write(obj: PixelFormat);  |
| 53 | chunk.Write(obj: Width);  |
| 54 | chunk.Write(obj: Height);  |
| 55 | }  |
| 56 | chunk.End();  |
| 57 |   |
| 58 | chunk.Begin(chunkID: tChunkID::Image_LayerData);  |
| 59 | {  |
| 60 | int dataSize = GetDataSize();  |
| 61 | chunk.Write(data: Data, numItems: dataSize);  |
| 62 | }  |
| 63 | chunk.End();  |
| 64 | }  |
| 65 | chunk.End();  |
| 66 | }  |
| 67 |   |
| 68 |   |
| 69 | void tLayer::Load(const tChunk& chunk, bool ownsData)  |
| 70 | {  |
| 71 | Clear();  |
| 72 | if (chunk.ID() != tChunkID::Image_Layer)  |
| 73 | return;  |
| 74 |   |
| 75 | OwnsData = ownsData;  |
| 76 | for (tChunk ch = chunk.First(); ch.IsValid(); ch = ch.Next())  |
| 77 | {  |
| 78 | switch (ch.ID())  |
| 79 | {  |
| 80 | // This chunk must be loaded first.  |
| 81 | case tChunkID::Image_LayerProperties:  |
| 82 | {  |
| 83 | ch.GetItem(item&: PixelFormat);  |
| 84 | ch.GetItem(item&: Width);  |
| 85 | ch.GetItem(item&: Height);  |
| 86 | break;  |
| 87 | }  |
| 88 |   |
| 89 | case tChunkID::Image_LayerData:  |
| 90 | {  |
| 91 | int dataSize = GetDataSize();  |
| 92 | if (dataSize <= 0)  |
| 93 | return;  |
| 94 |   |
| 95 | tAssert(!Data);  |
| 96 | if (OwnsData)  |
| 97 | {  |
| 98 | Data = new uint8[dataSize];  |
| 99 | tStd::tMemcpy(dest: Data, src: ch.Data(), numBytes: dataSize);  |
| 100 | }  |
| 101 | else  |
| 102 | {  |
| 103 | Data = (uint8*)ch.Data();  |
| 104 | }  |
| 105 | break;  |
| 106 | }  |
| 107 | }  |
| 108 | }  |
| 109 | }  |
| 110 | |