comparison tools/lib64gfx.c @ 1463:bde6a66bc2f6

Change dmDecodeGenericRLE() to use DMGrowBuf as output. Also add support for two different common types of RLE encoding. Add stub function of dmEncodeGenericRLE(), not implemented yet. Change functions using dmDecodeGenericRLE to use the new API. Also fix a problem in Amica Paint RLE decoding as the format seems to save one byte less than is necessary.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 10 May 2018 21:27:24 +0300
parents 9cb6dd1046bf
children 88845f95e791
comparison
equal deleted inserted replaced
1462:9cb6dd1046bf 1463:bde6a66bc2f6
31 { 0x9A, 0xD2, 0x84, 0xff }, 31 { 0x9A, 0xD2, 0x84, 0xff },
32 { 0x6C, 0x5E, 0xB5, 0xff }, 32 { 0x6C, 0x5E, 0xB5, 0xff },
33 { 0x95, 0x95, 0x95, 0xff }, 33 { 0x95, 0x95, 0x95, 0xff },
34 }; 34 };
35 35
36 #define DM_RLE_MARKER 1
37 #define DM_RLE_MASK 2
38
36 39
37 #define DM_GET_ADDR_LO(addr) ((addr) & 0xff) 40 #define DM_GET_ADDR_LO(addr) ((addr) & 0xff)
38 #define DM_GET_ADDR_HI(addr) (((addr) >> 8) & 0xff) 41 #define DM_GET_ADDR_HI(addr) (((addr) >> 8) & 0xff)
39 42
40 43
220 223
221 return DMERR_OK; 224 return DMERR_OK;
222 } 225 }
223 226
224 227
225 static int dmDecodeGenericRLE(Uint8 **mem, Uint8 **pdstEnd, const Uint8 *src, const Uint8 *srcEnd, const Uint8 rleMarker) 228 static int dmDecodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const Uint8 rleMarker, const Uint8 rleMask, const int rleType)
226 { 229 {
227 Uint8 *dst, *dstEnd; 230 int res;
228 231
229 if ((*mem = dmMalloc(C64_RAM_SIZE)) == NULL) 232 if ((res = dmGrowBufAlloc(dst, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK)
230 return DMERR_MALLOC; 233 goto err;
231 234
232 dst = *mem; 235 // Perform RLE decode
233 dstEnd = *mem + C64_RAM_SIZE; 236 while (src < srcEnd)
234
235 while (src <= srcEnd && dst <= dstEnd)
236 { 237 {
237 Uint8 c = *src++; 238 Uint8 c = *src++;
238 if (c == rleMarker && src + 2 <= srcEnd) 239 int cnt = 1;
239 { 240
240 int cnt = *src++; 241 switch (rleType)
241 c = *src++; 242 {
242 while (cnt-- && dst <= dstEnd) 243 case DM_RLE_MARKER:
243 *dst++ = c; 244 if (c == rleMarker)
244 } 245 {
245 else 246 if (srcEnd - src < 2)
246 *dst++ = c; 247 {
247 } 248 res = dmError(DMERR_INVALID_DATA,
248 249 "Foobar: %d\n", srcEnd - src);
249 *pdstEnd = dst; 250 goto err;
250 251 }
252 cnt = *src++;
253 c = *src++;
254 }
255 break;
256
257 case DM_RLE_MASK:
258 if ((c & rleMask) == rleMarker)
259 {
260 if (srcEnd - src < 1)
261 {
262 res = dmError(DMERR_INVALID_DATA,
263 "foobar2\n");
264 goto err;
265 }
266 // XXX TODO actually we probably want another mask here
267 cnt = c & (0xff ^ rleMask);
268 c = *src++;
269 }
270 break;
271 }
272
273 while (cnt--)
274 {
275 if (!dmGrowBufPutU8(dst, c))
276 {
277 res = dmError(DMERR_MALLOC,
278 "bazzooo\n");
279 goto err;
280 }
281 }
282 }
283
284 // Reallocate the memory
285 if ((res = dmGrowBufResize(dst)) != DMERR_OK)
286 goto err;
287
288 res = DMERR_OK;
289
290 err:
291 return res;
292 }
293
294
295 static int dmEncodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const Uint8 rleMarker)
296 {
297 (void) dst;
298 (void) src;
299 (void) srcEnd;
300 (void) rleMarker;
251 return DMERR_OK; 301 return DMERR_OK;
252 } 302 }
253 303
254 304
255 static inline Uint8 dmC64GetGenericSCPixel( 305 static inline Uint8 dmC64GetGenericSCPixel(
314 364
315 365
316 static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 366 static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
317 { 367 {
318 int res; 368 int res;
319 Uint8 *mem = NULL, *end; 369 DMGrowBuf mem;
320 370
321 if ((res = dmDecodeGenericRLE(&mem, &end, buf + 0x0e, buf + len - 1, *(buf + 0x0d))) != DMERR_OK) 371 if ((res = dmDecodeGenericRLE(&mem, buf + 0x0e, buf + len, *(buf + 0x0d), 0, DM_RLE_MARKER)) != DMERR_OK)
322 goto out; 372 goto out;
323 373
324 res = dmC64DecodeGenericBMP(img, mem, end - mem + 1, fmt); 374 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt);
325 375
326 out: 376 out:
327 dmFree(mem); 377 dmGrowBufFree(&mem);
328 return res; 378 return res;
329 } 379 }
330 380
331 381
332 static int fmtProbeDrazLace10Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 382 static int fmtProbeDrazLace10Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
386 436
387 437
388 static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 438 static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
389 { 439 {
390 int res; 440 int res;
391 Uint8 *mem = NULL, *end; 441 DMGrowBuf mem, tmp;
392 442
393 if ((res = dmDecodeGenericRLE(&mem, &end, buf, buf + len - 1, 0xC2)) != DMERR_OK) 443 // Amica Paint apparently is broken and stores one byte less than it should
444 // so we need to do some crappy buffer expansion here ..
445 if ((res = dmGrowBufAlloc(&tmp, len + 4, 4)) != DMERR_OK)
446 return res;
447
448 tmp.len = len;
449 memcpy(tmp.data, buf, len);
450 tmp.data[tmp.len++] = 0;
451
452 // Now do an RLE decode on the enlarged buffer
453 if ((res = dmDecodeGenericRLE(&mem, tmp.data, tmp.data + tmp.len, 0xC2, 0, DM_RLE_MARKER)) != DMERR_OK)
394 goto out; 454 goto out;
395 455
396 res = dmC64DecodeGenericBMP(img, mem, end - mem + 1, fmt); 456 // And finally decode to bitmap struct
457 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt);
397 458
398 out: 459 out:
399 dmFree(mem); 460 dmGrowBufFree(&tmp);
461 dmGrowBufFree(&mem);
400 return res; 462 return res;
401 } 463 }
402 464
403 465
404 static int fmtProbeFLIDesigner(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 466 static int fmtProbeFLIDesigner(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
500 562
501 563
502 static int fmtDecodeFunPaint2Packed(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 564 static int fmtDecodeFunPaint2Packed(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
503 { 565 {
504 int res; 566 int res;
505 Uint8 *mem = NULL, *end; 567 DMGrowBuf mem;
506 568 dmGrowBufInit(&mem);
507 if ((res = dmDecodeGenericRLE(&mem, &end, buf + FUNPAINT2_HEADER_SIZE, buf + len - 1, *(buf + 15))) != DMERR_OK) 569
570 if ((res = dmDecodeGenericRLE(&mem, buf + FUNPAINT2_HEADER_SIZE, buf + len, *(buf + 15), 0, DM_RLE_MARKER)) != DMERR_OK)
508 goto out; 571 goto out;
509 572
510 res = dmC64DecodeGenericBMP(img, mem, end - mem + 1, fmt); 573 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt);
511 574
512 out: 575 out:
513 dmFree(mem); 576 dmGrowBufFree(&mem);
514 return res; 577 return res;
515 } 578 }
516 579
517 580
518 static Uint8 fmtGetPixelFunPaint2( 581 static Uint8 fmtGetPixelFunPaint2(