1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21#include "CompressedImageData.h"
22
23namespace love
24{
25namespace image
26{
27
28love::Type CompressedImageData::type("CompressedImageData", &Data::type);
29
30CompressedImageData::CompressedImageData(const std::list<FormatHandler *> &formats, Data *filedata)
31 : format(PIXELFORMAT_UNKNOWN)
32 , sRGB(false)
33{
34 FormatHandler *parser = nullptr;
35
36 for (FormatHandler *handler : formats)
37 {
38 if (handler->canParseCompressed(filedata))
39 {
40 parser = handler;
41 break;
42 }
43 }
44
45 if (parser == nullptr)
46 throw love::Exception("Could not parse compressed data: Unknown format.");
47
48 memory = parser->parseCompressed(filedata, dataImages, format, sRGB);
49
50 if (memory == nullptr)
51 throw love::Exception("Could not parse compressed data.");
52
53 if (format == PIXELFORMAT_UNKNOWN)
54 throw love::Exception("Could not parse compressed data: Unknown format.");
55
56 if (dataImages.size() == 0 || memory->size == 0)
57 throw love::Exception("Could not parse compressed data: No valid data?");
58}
59
60CompressedImageData::CompressedImageData(const CompressedImageData &c)
61 : format(c.format)
62 , sRGB(c.sRGB)
63{
64 memory.set(new CompressedMemory(c.memory->size), Acquire::NORETAIN);
65 memcpy(memory->data, c.memory->data, memory->size);
66
67 for (const auto &i : c.dataImages)
68 {
69 auto slice = new CompressedSlice(i->getFormat(), i->getWidth(), i->getHeight(), memory, i->getOffset(), i->getSize());
70 dataImages.push_back(slice);
71 slice->release();
72 }
73}
74
75CompressedImageData *CompressedImageData::clone() const
76{
77 return new CompressedImageData(*this);
78}
79
80CompressedImageData::~CompressedImageData()
81{
82}
83
84size_t CompressedImageData::getSize() const
85{
86 return memory->size;
87}
88
89void *CompressedImageData::getData() const
90{
91 return memory->data;
92}
93
94int CompressedImageData::getMipmapCount() const
95{
96 return (int) dataImages.size();
97}
98
99int CompressedImageData::getSliceCount(int /*mip*/) const
100{
101 return 1;
102}
103
104size_t CompressedImageData::getSize(int miplevel) const
105{
106 checkSliceExists(0, miplevel);
107
108 return dataImages[miplevel]->getSize();
109}
110
111void *CompressedImageData::getData(int miplevel) const
112{
113 checkSliceExists(0, miplevel);
114
115 return dataImages[miplevel]->getData();
116}
117
118int CompressedImageData::getWidth(int miplevel) const
119{
120 checkSliceExists(0, miplevel);
121
122 return dataImages[miplevel]->getWidth();
123}
124
125int CompressedImageData::getHeight(int miplevel) const
126{
127 checkSliceExists(0, miplevel);
128
129 return dataImages[miplevel]->getHeight();
130}
131
132PixelFormat CompressedImageData::getFormat() const
133{
134 return format;
135}
136
137bool CompressedImageData::isSRGB() const
138{
139 return sRGB;
140}
141
142CompressedSlice *CompressedImageData::getSlice(int slice, int miplevel) const
143{
144 checkSliceExists(slice, miplevel);
145
146 return dataImages[miplevel].get();
147}
148
149void CompressedImageData::checkSliceExists(int slice, int miplevel) const
150{
151 if (slice != 0)
152 throw love::Exception("Slice index %d does not exists", slice + 1);
153
154 if (miplevel < 0 || miplevel >= (int) dataImages.size())
155 throw love::Exception("Mipmap level %d does not exist", miplevel + 1);
156}
157
158} // image
159} // love
160