ScummVM API documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 
40 namespace AGS3 {
41 namespace AGS {
42 namespace Shared {
43 
44 class Bitmap;
45 
46 // TODO: research old version differences
47 enum 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 
58 enum 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
67 enum 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
74 enum 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 
84 enum SpriteCompression {
85  kSprCompress_None = 0,
86  kSprCompress_RLE,
87  kSprCompress_LZW,
88  kSprCompress_Deflate
89 };
90 
91 typedef 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
96  std::vector<int16_t> Widths;
97  std::vector<int16_t> Heights;
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.
127 class SpriteFile {
128 public:
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 
158 private:
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.
182 public:
184  ~SpriteFileWriter() {
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 
205 private:
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.
226 int 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
231 extern int SaveSpriteIndex(const String &filename, const SpriteFileIndex &index);
232 
233 } // namespace Shared
234 } // namespace AGS
235 } // namespace AGS3
236 
237 #endif
Definition: achievements_tables.h:27
Definition: allegro_bitmap.h:44
Definition: sprite_file.h:127
Definition: utility.h:39
Definition: ptr.h:572
Definition: sprite_file.h:94
size_type size() const
Definition: array.h:315
Definition: sprite_file.h:109
Definition: string.h:62
Definition: stream.h:52
Definition: error.h:110
Definition: ags.h:40
Definition: sprite_file.h:181