ScummVM API documentation
sprite_file.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 //=============================================================================
23 //
24 // SpriteFile class handles sprite file parsing and streaming sprites.
25 // SpriteFileWriter manages writing sprites into the output stream one by one,
26 // accumulating index information, and may therefore be suitable for a variety
27 // of situations.
28 //
29 //=============================================================================
30
31#ifndef AGS_SHARED_AC_SPRITE_FILE_H
32#define AGS_SHARED_AC_SPRITE_FILE_H
33
34#include "ags/shared/core/types.h"
35#include "common/std/memory.h"
36#include "common/std/vector.h"
37#include "ags/shared/util/stream.h"
38#include "ags/globals.h"
39
40namespace AGS3 {
41namespace AGS {
42namespace Shared {
43
44class Bitmap;
45
46// TODO: research old version differences
47enum SpriteFileVersion {
48 kSprfVersion_Undefined = 0,
49 kSprfVersion_Uncompressed = 4,
50 kSprfVersion_Compressed = 5,
51 kSprfVersion_Last32bit = 6,
52 kSprfVersion_64bit = 10,
53 kSprfVersion_HighSpriteLimit = 11,
54 kSprfVersion_StorageFormats = 12,
55 kSprfVersion_Current = kSprfVersion_StorageFormats
56};
57
58enum SpriteIndexFileVersion {
59 kSpridxfVersion_Initial = 1,
60 kSpridxfVersion_Last32bit = 2,
61 kSpridxfVersion_64bit = 10,
62 kSpridxfVersion_HighSpriteLimit = 11,
63 kSpridxfVersion_Current = kSpridxfVersion_HighSpriteLimit
64};
65
66// Instructions to how the sprites are allowed to be stored
67enum SpriteStorage {
68 // When possible convert the sprite into another format for less disk space
69 // e.g. save 16/32-bit images as 8-bit colormaps with palette
70 kSprStore_OptimizeForSize = 0x01
71};
72
73// Format in which the sprite's pixel data is stored
74enum SpriteFormat {
75 kSprFmt_Undefined = 0, // undefined, or keep as-is
76 // Encoded as a 8-bit colormap with palette of 24-bit RGB values
77 kSprFmt_PaletteRgb888 = 32,
78 // Encoded as a 8-bit colormap with palette of 32-bit ARGB values
79 kSprFmt_PaletteArgb8888 = 33,
80 // Encoded as a 8-bit colormap with palette of 16-bit RGB565 values
81 kSprFmt_PaletteRgb565 = 34
82};
83
84enum SpriteCompression {
85 kSprCompress_None = 0,
86 kSprCompress_RLE,
87 kSprCompress_LZW,
88 kSprCompress_Deflate
89};
90
91typedef int32_t sprkey_t;
92
93// SpriteFileIndex contains sprite file's table of contents
95 int SpriteFileIDCheck = 0; // tag matching sprite file and index file
98 std::vector<soff_t> Offsets;
99
100 inline size_t GetCount() const {
101 return Offsets.size();
102 }
103 inline sprkey_t GetLastSlot() const {
104 return (sprkey_t)GetCount() - 1;
105 }
106};
107
108// Invidual sprite data header (as read from the file)
110 int BPP = 0; // color depth (bytes per pixel); or input format
111 SpriteFormat SFormat = kSprFmt_Undefined; // storage format
112 uint32_t PalCount = 0; // palette length, if applicable to storage format
113 SpriteCompression Compress = kSprCompress_None; // compression type
114 int Width = 0; // sprite's width
115 int Height = 0; // sprite's height
116
117 SpriteDatHeader() = default;
118 SpriteDatHeader(int bpp, SpriteFormat sformat = kSprFmt_Undefined,
119 uint32_t pal_count = 0, SpriteCompression compress = kSprCompress_None,
120 int w = 0, int h = 0) : BPP(bpp), SFormat(sformat), PalCount(pal_count),
121 Compress(compress), Width(w), Height(h) {
122 }
123};
124
125// SpriteFile opens a sprite file for reading, reports general information,
126// and lets read sprites in any order.
128public:
129 // Standart sprite file and sprite index names
130 static const char *DefaultSpriteFileName;
131 static const char *DefaultSpriteIndexName;
132
133 SpriteFile();
134 // Loads sprite reference information and inits sprite stream
135 HError OpenFile(const String &filename, const String &sprindex_filename,
136 std::vector<Size> &metrics);
137 // Closes stream; no reading will be possible unless opened again
138 void Close();
139
140 int GetStoreFlags() const;
141 // Tells if bitmaps in the file are compressed
142 SpriteCompression GetSpriteCompression() const;
143 // Tells the highest known sprite index
144 sprkey_t GetTopmostSprite() const;
145
146 // Loads sprite index file
147 bool LoadSpriteIndexFile(const String &filename, int expectedFileID,
148 soff_t spr_initial_offs, sprkey_t topmost, std::vector<Size> &metrics);
149 // Rebuilds sprite index from the main sprite file
150 HError RebuildSpriteIndex(Stream *in, sprkey_t topmost,
151 std::vector<Size> &metrics);
152
153 // Loads an image data and creates a ready bitmap
154 HError LoadSprite(sprkey_t index, Bitmap *&sprite);
155 // Loads a raw sprite element data into the buffer, stores header info separately
156 HError LoadRawData(sprkey_t index, SpriteDatHeader &hdr, std::vector<uint8_t> &data);
157
158private:
159 // Seek stream to sprite
160 void SeekToSprite(sprkey_t index);
161
162 // Internal sprite reference
163 struct SpriteRef {
164 soff_t Offset = 0; // data offset
165 size_t RawSize = 0; // file size of element, in bytes
166 // TODO: RawSize is currently unused, due to incompleteness of spriteindex format
167 };
168
169 // Array of sprite references
170 std::vector<SpriteRef> _spriteData;
171 std::unique_ptr<Stream> _stream; // the sprite stream
172 SpriteFileVersion _version = kSprfVersion_Current;
173 int _storeFlags = 0; // storage flags, specify how sprites may be stored
174 SpriteCompression _compress = kSprCompress_None; // sprite compression typ
175 sprkey_t _curPos; // current stream position (sprite slot)
176};
177
178// SpriteFileWriter class writes a sprite file in a requested format.
179// Start using it by calling Begin, write ready bitmaps or copy raw sprite data
180// over slot by slot, then call Finalize to let it close the format correctly.
182public:
185 }
186
187 // Get the sprite index, accumulated after write
188 const SpriteFileIndex &GetIndex() const {
189 return _index;
190 }
191
192 // Initializes new sprite file format;
193 // store_flags are SpriteStorage;
194 // optionally hint how many sprites will be written.
195 void Begin(int store_flags, SpriteCompression compress, sprkey_t last_slot = -1);
196 // Writes a bitmap into file, compressing if necessary
197 void WriteBitmap(Bitmap *image);
198 // Writes an empty slot marker
199 void WriteEmptySlot();
200 // Writes a raw sprite data without any additional processing
201 void WriteRawData(const SpriteDatHeader &hdr, const uint8_t *data, size_t data_sz);
202 // Finalizes current format; no further writing is possible after this
203 void Finalize();
204
205private:
206 // Writes prepared image data in a proper file format, following explicit data_bpp rule
207 void WriteSpriteData(const SpriteDatHeader &hdr,
208 const uint8_t *im_data, size_t im_data_sz, int im_bpp,
209 const uint32_t palette[256]);
210
212 int _storeFlags = 0;
213 SpriteCompression _compress = kSprCompress_None;
214 soff_t _lastSlotPos = -1; // last slot save position in file
215 // sprite index accumulated on write for reporting back to user
216 SpriteFileIndex _index;
217 // compression buffer
218 std::vector<uint8_t> _membuf;
219};
220
221// Saves all sprites to file; fills in index data for external use.
222// TODO: refactor to be able to save main file and index file separately (separate function for gather data?)
223// Accepts available sprites as pairs of bool and Bitmap pointer, where boolean value
224// tells if sprite exists and Bitmap pointer may be null;
225// If a sprite's bitmap is missing, it will try reading one from the input file stream.
226int SaveSpriteFile(const String &save_to_file,
227 const std::vector<std::pair<bool, Bitmap *> > &sprites,
228 SpriteFile *read_from_file, // optional file to read missing sprites from
229 int store_flags, SpriteCompression compress, SpriteFileIndex &index);
230// Saves sprite index table in a separate file
231extern int SaveSpriteIndex(const String &filename, const SpriteFileIndex &index);
232
233} // namespace Shared
234} // namespace AGS
235} // namespace AGS3
236
237#endif
Definition: allegro_bitmap.h:44
Definition: error.h:110
Definition: sprite_file.h:127
Definition: sprite_file.h:181
Definition: stream.h:52
Definition: string.h:60
size_type size() const
Definition: array.h:316
Definition: ptr.h:572
Definition: sprite_file.h:109
Definition: sprite_file.h:94
Definition: utility.h:39