Ticket #9070: endianstream.patch
File endianstream.patch, 17.3 KB (added by , 16 years ago) |
---|
-
common/endian.h
32 32 // Endian conversion functions, macros etc., follow from here! 33 33 // 34 34 35 // Sanity check 36 #if !defined(SCUMM_LITTLE_ENDIAN) && !defined(SCUMM_BIG_ENDIAN) 37 # error No endianness defined 38 #endif 39 35 40 /** 36 41 * Swap the bytes in a 32 bit word in order to convert LE encoded data to BE 37 42 * and vice versa. 43 * compilerspecific variants come first, fallback last 38 44 */ 39 FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) {40 return ((a >> 24) & 0x000000FF) |41 ((a >> 8) & 0x0000FF00) |42 ((a << 8) & 0x00FF0000) |43 ((a << 24) & 0xFF000000);44 }45 45 46 // Test for GCC >= 4.3.0 as this version added the bswap builtin 47 #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) 48 49 FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) { 50 return __builtin_bswap32(a); 51 } 52 53 // test for MSVC 7 or newer 54 #elif defined(_MSC_VER) && _MSC_VER >= 1300 55 56 FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) { 57 return _byteswap_ulong(a); 58 } 59 60 // generic fallback 61 #else 62 63 inline uint32 SWAP_BYTES_32(uint32 a) { 64 const uint16 low = (uint16)a, high = (uint16)(a >> 16); 65 return ((uint32)(uint16)((low >> 8) | (low << 8)) << 16) 66 | (uint16)((high >> 8) | (high << 8)); 67 } 68 #endif 69 46 70 /** 47 71 * Swap the bytes in a 16 bit word in order to convert LE encoded data to BE 48 72 * and vice versa. 49 73 */ 50 FORCEINLINE uint16 SWAP_BYTES_16( uint16 a) {51 return ( (a >> 8) & 0x00FF) + ((a << 8) & 0xFF00);74 FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) { 75 return (a >> 8) | (a << 8); 52 76 } 53 77 54 78 … … 70 94 * For the latter systems we provide the INVERSE_MKID override. 71 95 */ 72 96 #if defined(INVERSE_MKID) 73 #define MKID_BE(a) ((uint32) \74 (((a) >> 24) & 0x00 0000FF) | \75 (((a) >> 8) & 0x 0000FF00) | \76 (((a) << 8) & 0x00FF0000) | \77 (((a) << 24) & 0xFF000000))97 #define MKID_BE(a) ((uint32)( \ 98 (((a) >> 24) & 0x00FF) | \ 99 (((a) >> 8) & 0xFF00) | \ 100 (((a) & 0xFF00) << 8) | \ 101 (((a) & 0x00FF) << 24) )) 78 102 79 103 #else 80 104 # define MKID_BE(a) ((uint32)(a)) 81 105 #endif 82 106 107 // Functions for reading/writing native Integers, 108 // this transparently handles the need for alignment 83 109 110 #if !defined(SCUMM_NEED_ALIGNMENT) 84 111 112 FORCEINLINE uint16 READ_UINT16(const void *ptr) { 113 return *(const uint16 *)(ptr); 114 } 115 116 FORCEINLINE uint32 READ_UINT32(const void *ptr) { 117 return *(const uint32 *)(ptr); 118 } 119 120 FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) { 121 *(uint16 *)(ptr) = value; 122 } 123 124 FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) { 125 *(uint32 *)(ptr) = value; 126 } 127 128 // test for GCC >= 4.0. these implementations will automatically use CPU-specific 129 // instructions for unaligned data when they are available (eg. MIPS) 130 #elif defined(__GNUC__) && (__GNUC__ >= 4) 131 132 FORCEINLINE uint16 READ_UINT16(const void *ptr) { 133 struct Unaligned16 { uint16 val; } __attribute__ ((__packed__)); 134 return ((const Unaligned16 *)ptr)->val; 135 } 136 137 FORCEINLINE uint32 READ_UINT32(const void *ptr) { 138 struct Unaligned32 { uint32 val; } __attribute__ ((__packed__)); 139 return ((const Unaligned32 *)ptr)->val; 140 } 141 142 FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) { 143 struct Unaligned16 { uint16 val; } __attribute__ ((__packed__)); 144 ((Unaligned16 *)ptr)->val = value; 145 } 146 147 FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) { 148 struct Unaligned32 { uint32 val; } __attribute__ ((__packed__)); 149 ((Unaligned32 *)ptr)->val = value; 150 } 151 152 // use software fallback by loading each byte explicitely 153 #else 154 155 # if defined(SCUMM_LITTLE_ENDIAN) 156 157 FORCEINLINE uint16 READ_UINT16(const void *ptr) { 158 const uint8 *b = (const uint8 *)ptr; 159 return (b[1] << 8) | b[0]; 160 } 161 inline uint32 READ_UINT32(const void *ptr) { 162 const uint8 *b = (const uint8 *)ptr; 163 return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]); 164 } 165 FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) { 166 uint8 *b = (uint8 *)ptr; 167 b[0] = (uint8)(value >> 0); 168 b[1] = (uint8)(value >> 8); 169 } 170 inline void WRITE_UINT32(void *ptr, uint32 value) { 171 uint8 *b = (uint8 *)ptr; 172 b[0] = (uint8)(value >> 0); 173 b[1] = (uint8)(value >> 8); 174 b[2] = (uint8)(value >> 16); 175 b[3] = (uint8)(value >> 24); 176 } 177 178 # elif defined(SCUMM_BIG_ENDIAN) 179 180 FORCEINLINE uint16 READ_UINT16(const void *ptr) { 181 const uint8 *b = (const uint8 *)ptr; 182 return (b[0] << 8) | b[1]; 183 } 184 inline uint32 READ_UINT32(const void *ptr) { 185 const uint8 *b = (const uint8 *)ptr; 186 return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]); 187 } 188 FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) { 189 uint8 *b = (uint8 *)ptr; 190 b[0] = (uint8)(value >> 8); 191 b[1] = (uint8)(value >> 0); 192 } 193 inline void WRITE_UINT32(void *ptr, uint32 value) { 194 uint8 *b = (uint8 *)ptr; 195 b[0] = (uint8)(value >> 24); 196 b[1] = (uint8)(value >> 16); 197 b[2] = (uint8)(value >> 8); 198 b[3] = (uint8)(value >> 0); 199 } 200 201 # endif 202 203 #endif 204 205 206 // Map Funtions for reading/writing BE/LE integers depending on native endianess 85 207 #if defined(SCUMM_LITTLE_ENDIAN) 86 208 87 #define READ_ UINT16(a) READ_LE_UINT16(a)88 #define READ_ UINT32(a) READ_LE_UINT32(a)209 #define READ_LE_UINT16(a) READ_UINT16(a) 210 #define READ_LE_UINT32(a) READ_UINT32(a) 89 211 90 #define WRITE_ UINT16(a, v) WRITE_LE_UINT16(a, v)91 #define WRITE_ UINT32(a, v) WRITE_LE_UINT32(a, v)212 #define WRITE_LE_UINT16(a, v) WRITE_UINT16(a, v) 213 #define WRITE_LE_UINT32(a, v) WRITE_UINT32(a, v) 92 214 93 215 #define FROM_LE_32(a) ((uint32)(a)) 94 216 #define FROM_LE_16(a) ((uint16)(a)) … … 102 224 #define TO_BE_32(a) SWAP_BYTES_32(a) 103 225 #define TO_BE_16(a) SWAP_BYTES_16(a) 104 226 227 # if defined(SCUMM_NEED_ALIGNMENT) 228 229 FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) { 230 const uint8 *b = (const uint8 *)ptr; 231 return (b[0] << 8) | b[1]; 232 } 233 inline uint32 READ_BE_UINT32(const void *ptr) { 234 const uint8 *b = (const uint8 *)ptr; 235 return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]); 236 } 237 FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) { 238 uint8 *b = (uint8 *)ptr; 239 b[0] = (uint8)(value >> 8); 240 b[1] = (uint8)(value >> 0); 241 } 242 inline void WRITE_BE_UINT32(void *ptr, uint32 value) { 243 uint8 *b = (uint8 *)ptr; 244 b[0] = (uint8)(value >> 24); 245 b[1] = (uint8)(value >> 16); 246 b[2] = (uint8)(value >> 8); 247 b[3] = (uint8)(value >> 0); 248 } 249 # else 250 251 FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) { 252 return SWAP_BYTES_16(*(const uint16 *)ptr); 253 } 254 FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) { 255 return SWAP_BYTES_32(*(const uint32 *)ptr); 256 } 257 FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) { 258 *(uint16 *)ptr = SWAP_BYTES_16(value); 259 } 260 FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) { 261 *(uint32 *)ptr = SWAP_BYTES_32(value); 262 } 263 264 # endif // if defined(SCUMM_NEED_ALIGNMENT) 265 105 266 #elif defined(SCUMM_BIG_ENDIAN) 106 267 268 // I thought this would be compiler-specific and not dependent 269 // on endianess after the comments above? 107 270 #define MKID(a) ((uint32)(a)) 108 271 #define MKID_BE(a) ((uint32)(a)) 109 272 110 #define READ_ UINT16(a) READ_BE_UINT16(a)111 #define READ_ UINT32(a) READ_BE_UINT32(a)273 #define READ_BE_UINT16(a) READ_UINT16(a) 274 #define READ_BE_UINT32(a) READ_UINT32(a) 112 275 113 #define WRITE_ UINT16(a, v) WRITE_BE_UINT16(a, v)114 #define WRITE_ UINT32(a, v) WRITE_BE_UINT32(a, v)276 #define WRITE_BE_UINT16(a, v) WRITE_UINT16(a, v) 277 #define WRITE_BE_UINT32(a, v) WRITE_UINT32(a, v) 115 278 116 279 #define FROM_LE_32(a) SWAP_BYTES_32(a) 117 280 #define FROM_LE_16(a) SWAP_BYTES_16(a) … … 125 288 #define TO_BE_32(a) ((uint32)(a)) 126 289 #define TO_BE_16(a) ((uint16)(a)) 127 290 128 # else291 # if defined(SCUMM_NEED_ALIGNMENT) 129 292 130 #error No endianness defined131 132 133 #endif134 135 136 #if defined(SCUMM_NEED_ALIGNMENT) || !defined(SCUMM_LITTLE_ENDIAN)137 293 FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) { 138 const byte *b = (const byte*)ptr;139 return (b[1] << 8) +b[0];294 const uint8 *b = (const uint8 *)ptr; 295 return (b[1] << 8) | b[0]; 140 296 } 141 FORCEINLINEuint32 READ_LE_UINT32(const void *ptr) {142 const byte *b = (const byte*)ptr;143 return (b[3] << 24) + (b[2] << 16) + (b[1] << 8) +(b[0]);297 inline uint32 READ_LE_UINT32(const void *ptr) { 298 const uint8 *b = (const uint8 *)ptr; 299 return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]); 144 300 } 145 301 FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) { 146 byte *b = (byte*)ptr;147 b[0] = ( byte)(value >> 0);148 b[1] = ( byte)(value >> 8);302 uint8 *b = (uint8 *)ptr; 303 b[0] = (uint8)(value >> 0); 304 b[1] = (uint8)(value >> 8); 149 305 } 150 FORCEINLINEvoid WRITE_LE_UINT32(void *ptr, uint32 value) {151 byte *b = (byte*)ptr;152 b[0] = ( byte)(value >> 0);153 b[1] = ( byte)(value >> 8);154 b[2] = ( byte)(value >> 16);155 b[3] = ( byte)(value >> 24);306 inline void WRITE_LE_UINT32(void *ptr, uint32 value) { 307 uint8 *b = (uint8 *)ptr; 308 b[0] = (uint8)(value >> 0); 309 b[1] = (uint8)(value >> 8); 310 b[2] = (uint8)(value >> 16); 311 b[3] = (uint8)(value >> 24); 156 312 } 157 #else 313 # else 314 158 315 FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) { 159 return *(const uint16 *)(ptr);316 return SWAP_BYTES_16(*(const uint16 *)ptr); 160 317 } 161 318 FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) { 162 return *(const uint32 *)(ptr);319 return SWAP_BYTES_32(*(const uint32 *)ptr); 163 320 } 164 321 FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) { 165 *(uint16 *) (ptr) = value;322 *(uint16 *)ptr = SWAP_BYTES_16(value); 166 323 } 167 324 FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) { 168 *(uint32 *) (ptr) = value;325 *(uint32 *)ptr = SWAP_BYTES_32(value); 169 326 } 170 #endif 327 328 # endif // if defined(SCUMM_NEED_ALIGNMENT) 171 329 330 #endif // if defined(SCUMM_LITTLE_ENDIAN) 172 331 173 #if defined(SCUMM_NEED_ALIGNMENT) || !defined(SCUMM_BIG_ENDIAN)174 FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) {175 const byte *b = (const byte *)ptr;176 return (b[0] << 8) + b[1];177 }178 FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) {179 const byte *b = (const byte*)ptr;180 return (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + (b[3]);181 }182 FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) {183 byte *b = (byte *)ptr;184 b[0] = (byte)(value >> 8);185 b[1] = (byte)(value >> 0);186 }187 FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) {188 byte *b = (byte *)ptr;189 b[0] = (byte)(value >> 24);190 b[1] = (byte)(value >> 16);191 b[2] = (byte)(value >> 8);192 b[3] = (byte)(value >> 0);193 }194 #else195 FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) {196 return *(const uint16 *)(ptr);197 }198 FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) {199 return *(const uint32 *)(ptr);200 }201 FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) {202 *(uint16 *)(ptr) = value;203 }204 FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) {205 *(uint32 *)(ptr) = value;206 }207 #endif208 209 332 FORCEINLINE uint32 READ_LE_UINT24(const void *ptr) { 210 const byte *b = (const byte*)ptr;211 return (b[2] << 16) + (b[1] << 8) +(b[0]);333 const uint8 *b = (const uint8 *)ptr; 334 return (b[2] << 16) | (b[1] << 8) | (b[0]); 212 335 } 213 336 214 337 FORCEINLINE uint32 READ_BE_UINT24(const void *ptr) { 215 const byte *b = (const byte*)ptr;216 return (b[0] << 16) + (b[1] << 8) +(b[2]);338 const uint8 *b = (const uint8 *)ptr; 339 return (b[0] << 16) | (b[1] << 8) | (b[2]); 217 340 } 218 341 219 220 342 #endif -
common/stream.h
27 27 #define COMMON_STREAM_H 28 28 29 29 #include "common/scummsys.h" 30 #include "common/endian.h" 30 31 31 32 namespace Common { 32 33 … … 106 107 } 107 108 108 109 void writeUint16LE(uint16 value) { 109 writeByte((byte)(value & 0xff));110 write Byte((byte)(value >> 8));110 value = TO_LE_16(value); 111 write(&value, 2); 111 112 } 112 113 113 114 void writeUint32LE(uint32 value) { 114 writeUint16LE((uint16)(value & 0xffff));115 write Uint16LE((uint16)(value >> 16));115 value = TO_LE_32(value); 116 write(&value, 4); 116 117 } 117 118 118 119 void writeUint16BE(uint16 value) { 119 writeByte((byte)(value >> 8));120 write Byte((byte)(value & 0xff));120 value = TO_BE_16(value); 121 write(&value, 2); 121 122 } 122 123 123 124 void writeUint32BE(uint32 value) { 124 writeUint16BE((uint16)(value >> 16));125 write Uint16BE((uint16)(value & 0xffff));125 value = TO_BE_32(value); 126 write(&value, 4); 126 127 } 127 128 128 void writeSint16LE(int16 value) {129 FORCEINLINE void writeSint16LE(int16 value) { 129 130 writeUint16LE((uint16)value); 130 131 } 131 132 132 void writeSint32LE(int32 value) {133 FORCEINLINE void writeSint32LE(int32 value) { 133 134 writeUint32LE((uint32)value); 134 135 } 135 136 136 void writeSint16BE(int16 value) {137 FORCEINLINE void writeSint16BE(int16 value) { 137 138 writeUint16BE((uint16)value); 138 139 } 139 140 140 void writeSint32BE(int32 value) {141 FORCEINLINE void writeSint32BE(int32 value) { 141 142 writeUint32BE((uint32)value); 142 143 } 143 144 … … 188 189 * calling err() and eos() ). 189 190 */ 190 191 byte readByte() { 191 byte b = 0; 192 byte b = 0; // FIXME: remove initialisation 192 193 read(&b, 1); 193 194 return b; 194 195 } … … 200 201 * calling err() and eos() ). 201 202 */ 202 203 int8 readSByte() { 203 int8 b = 0; 204 int8 b = 0; // FIXME: remove initialisation 204 205 read(&b, 1); 205 206 return b; 206 207 } … … 213 214 * calling err() and eos() ). 214 215 */ 215 216 uint16 readUint16LE() { 216 uint16 a = readByte();217 uint16 b = readByte();218 return a | (b << 8);217 uint16 val; 218 read(&val, 2); 219 return FROM_LE_16(val); 219 220 } 220 221 221 222 /** … … 226 227 * calling err() and eos() ). 227 228 */ 228 229 uint32 readUint32LE() { 229 uint32 a = readUint16LE();230 uint32 b = readUint16LE();231 return (b << 16) | a;230 uint32 val; 231 read(&val, 4); 232 return FROM_LE_32(val); 232 233 } 233 234 234 235 /** … … 239 240 * calling err() and eos() ). 240 241 */ 241 242 uint16 readUint16BE() { 242 uint16 b = readByte();243 uint16 a = readByte();244 return a | (b << 8);243 uint16 val; 244 read(&val, 2); 245 return FROM_BE_16(val); 245 246 } 246 247 247 248 /** … … 252 253 * calling err() and eos() ). 253 254 */ 254 255 uint32 readUint32BE() { 255 uint32 b = readUint16BE();256 uint32 a = readUint16BE();257 return (b << 16) | a;256 uint32 val; 257 read(&val, 4); 258 return FROM_BE_32(val); 258 259 } 259 260 260 261 /** … … 264 265 * if a read error occurred (for which client code can check by 265 266 * calling err() and eos() ). 266 267 */ 267 int16 readSint16LE() {268 FORCEINLINE int16 readSint16LE() { 268 269 return (int16)readUint16LE(); 269 270 } 270 271 … … 275 276 * if a read error occurred (for which client code can check by 276 277 * calling err() and eos() ). 277 278 */ 278 int32 readSint32LE() {279 FORCEINLINE int32 readSint32LE() { 279 280 return (int32)readUint32LE(); 280 281 } 281 282 … … 286 287 * if a read error occurred (for which client code can check by 287 288 * calling err() and eos() ). 288 289 */ 289 int16 readSint16BE() {290 FORCEINLINE int16 readSint16BE() { 290 291 return (int16)readUint16BE(); 291 292 } 292 293 … … 297 298 * if a read error occurred (for which client code can check by 298 299 * calling err() and eos() ). 299 300 */ 300 int32 readSint32BE() {301 FORCEINLINE int32 readSint32BE() { 301 302 return (int32)readUint32BE(); 302 303 } 303 304 … … 453 454 * read methods whose endianness is set on the stream creation. 454 455 */ 455 456 class SeekableSubReadStreamEndian : public SeekableSubReadStream { 457 private: 458 const bool _bigEndian; 459 456 460 public: 457 bool _bigEndian;458 459 461 SeekableSubReadStreamEndian(SeekableReadStream *parentStream, uint32 begin, uint32 end, bool bigEndian = false, bool disposeParentStream = false) 460 462 : SeekableSubReadStream(parentStream, begin, end, disposeParentStream), _bigEndian(bigEndian) { 461 463 } 462 464 463 inline uint16 readUint16() { 464 return (_bigEndian) ? readUint16BE() : readUint16LE(); 465 uint16 readUint16() { 466 uint16 val; 467 read(&val, 2); 468 return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val); 465 469 } 466 470 467 inline uint32 readUint32() { 468 return (_bigEndian) ? readUint32BE() : readUint32LE(); 471 uint32 readUint32() { 472 uint32 val; 473 read(&val, 4); 474 return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val); 469 475 } 470 476 471 inlineint16 readSint16() {477 FORCEINLINE int16 readSint16() { 472 478 return (int16)readUint16(); 473 479 } 474 480 475 inlineint32 readSint32() {481 FORCEINLINE int32 readSint32() { 476 482 return (int32)readUint32(); 477 483 } 478 484 }; … … 575 581 */ 576 582 class MemoryReadStreamEndian : public Common::MemoryReadStream { 577 583 private: 584 const bool _bigEndian; 585 578 586 public: 579 bool _bigEndian;580 587 MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian = false) : MemoryReadStream(buf, len), _bigEndian(bigEndian) {} 581 588 582 inline uint16 readUint16() { 583 return (_bigEndian) ? readUint16BE() : readUint16LE(); 589 uint16 readUint16() { 590 uint16 val; 591 read(&val, 2); 592 return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val); 584 593 } 585 594 586 inline uint32 readUint32() { 587 return (_bigEndian) ? readUint32BE() : readUint32LE(); 595 uint32 readUint32() { 596 uint32 val; 597 read(&val, 4); 598 return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val); 588 599 } 589 600 590 inlineint16 readSint16() {601 FORCEINLINE int16 readSint16() { 591 602 return (int16)readUint16(); 592 603 } 593 604 594 inlineint32 readSint32() {605 FORCEINLINE int32 readSint32() { 595 606 return (int32)readUint32(); 596 607 } 597 608 }; -
engines/saga/animation.cpp
826 826 int i; 827 827 bool longData = isLongData(); 828 828 829 MemoryReadStreamEndian readS(anim->resourceData, anim->resourceLength, _vm->isBigEndian());829 MemoryReadStreamEndian readS(anim->resourceData, anim->resourceLength, !_vm->isBigEndian()); // RLE has inversion BE<>LE 830 830 831 831 readS.seek(12); 832 832 833 readS._bigEndian = !_vm->isBigEndian(); // RLE has inversion BE<>LE834 835 833 while (readS.pos() != readS.size()) { 836 834 if (reallyFill) { 837 835 anim->frameOffsets[currentFrame] = readS.pos();