comparison tools/lib64fmts.c @ 1707:a0986cfd6f9d

More consistently use DMGrowBuf in the lib64gfx APIs, and implement "backwards" RLE decoding and encoding (optionally regards input/output). Not tested very much yet, there may be bugs.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 05 Jun 2018 21:58:10 +0300
parents 1036b0dcccb5
children 4fd94bf558b3
comparison
equal deleted inserted replaced
1706:311b14855a1e 1707:a0986cfd6f9d
29 { 0x6C, 0x5E, 0xB5, 0xff }, 29 { 0x6C, 0x5E, 0xB5, 0xff },
30 { 0x95, 0x95, 0x95, 0xff }, 30 { 0x95, 0x95, 0x95, 0xff },
31 }; 31 };
32 32
33 33
34
35 static int fmtProbeKoalaPaintPacked(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 34 static int fmtProbeKoalaPaintPacked(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
36 { 35 {
37 // Attempt to prevent misprobes of unpacked Koala and Run Paint 36 // Attempt to prevent misprobes of unpacked Koala and Run Paint
38 if (len > 30 && 37 if (len > 30 &&
39 len != 10006 && 38 len != 10006 &&
43 42
44 return DM_PROBE_SCORE_FALSE; 43 return DM_PROBE_SCORE_FALSE;
45 } 44 }
46 45
47 46
48 static int fmtDecodeKoalaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 47 static int fmtDecodeKoalaPaintPacked(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt)
49 { 48 {
50 int res; 49 int res;
51 DMGrowBuf mem; 50 DMGrowBuf mem;
52 DMCompParams cfg; 51 DMCompParams cfg;
53 52
54 cfg.type = DM_COMP_RLE_MARKER; 53 cfg.type = DM_COMP_RLE_MARKER;
55 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_2; 54 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_2;
56 cfg.rleMarkerB = 0xfe; 55 cfg.rleMarkerB = 0xfe;
57 if ((res = dmDecodeGenericRLEAlloc(&mem, buf, buf + len, &cfg)) != DMERR_OK) 56
57 if ((res = dmDecodeGenericRLEAlloc(&mem, buf, &cfg)) != DMERR_OK)
58 goto out; 58 goto out;
59 59
60 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); 60 res = dmC64DecodeGenericBMP(img, &mem, fmt);
61 61
62 out: 62 out:
63 dmGrowBufFree(&mem); 63 dmGrowBufFree(&mem);
64 return res; 64 return res;
65 } 65 }
79 cfg.type = DM_COMP_RLE_MARKER; 79 cfg.type = DM_COMP_RLE_MARKER;
80 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_2; 80 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_2;
81 cfg.rleMarkerB = 0xfe; 81 cfg.rleMarkerB = 0xfe;
82 cfg.rleMinCountB = 3; 82 cfg.rleMinCountB = 3;
83 cfg.rleMaxCountB = 255; 83 cfg.rleMaxCountB = 255;
84 res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); 84 res = dmEncodeGenericRLE(buf, &tmp, &cfg);
85 85
86 out: 86 out:
87 dmGrowBufFree(&tmp); 87 dmGrowBufFree(&tmp);
88 return res; 88 return res;
89 } 89 }
103 103
104 return DM_PROBE_SCORE_FALSE; 104 return DM_PROBE_SCORE_FALSE;
105 } 105 }
106 106
107 107
108 static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 108 static int fmtDecodeDrazPaintPacked(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt)
109 { 109 {
110 int res; 110 int res;
111 DMGrowBuf mem; 111 DMGrowBuf mem, tmp;
112 DMCompParams cfg; 112 DMCompParams cfg;
113 113
114 cfg.type = DM_COMP_RLE_MARKER; 114 cfg.type = DM_COMP_RLE_MARKER;
115 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; 115 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1;
116 cfg.rleMarkerB = buf[0x0d]; 116 cfg.rleMarkerB = buf->data[0x0d];
117 117
118 if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 0x0e, buf + len, &cfg)) != DMERR_OK) 118 if ((res = dmDecodeGenericRLEAlloc(&mem,
119 dmGrowBufCreateFromOffs(&tmp, buf, 0x0e), &cfg)) != DMERR_OK)
119 goto out; 120 goto out;
120 121
121 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); 122 res = dmC64DecodeGenericBMP(img, &mem, fmt);
122 123
123 out: 124 out:
124 dmGrowBufFree(&mem); 125 dmGrowBufFree(&mem);
125 return res; 126 return res;
126 } 127 }
141 cfg.type = DM_COMP_RLE_MARKER; 142 cfg.type = DM_COMP_RLE_MARKER;
142 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; 143 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1;
143 cfg.rleMinCountB = 3; 144 cfg.rleMinCountB = 3;
144 cfg.rleMaxCountB = 255; 145 cfg.rleMaxCountB = 255;
145 146
146 dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); 147 dmGenericRLEAnalyze(&tmp, &cfg);
147 148
148 // Add the header bits 149 // Add the header bits
149 if (!dmGrowBufPut(buf, (Uint8 *) magicID, strlen(magicID)) || 150 if (!dmGrowBufPut(buf, (Uint8 *) magicID, strlen(magicID)) ||
150 !dmGrowBufPutU8(buf, cfg.rleMarkerB)) 151 !dmGrowBufPutU8(buf, cfg.rleMarkerB))
151 { 152 {
152 res = DMERR_MALLOC; 153 res = DMERR_MALLOC;
153 goto out; 154 goto out;
154 } 155 }
155 156
156 // And now RLE compress the data to the existing buffer 157 // And now RLE compress the data to the existing buffer
157 res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); 158 res = dmEncodeGenericRLE(buf, &tmp, &cfg);
158 159
159 out: 160 out:
160 dmGrowBufFree(&tmp); 161 dmGrowBufFree(&tmp);
161 return res; 162 return res;
162 } 163 }
172 return DM_PROBE_SCORE_FALSE; 173 return DM_PROBE_SCORE_FALSE;
173 } 174 }
174 175
175 176
176 static BOOL fmtDrazLaceGetLaceType(DMC64Image *img, const DMC64EncDecOp *op, 177 static BOOL fmtDrazLaceGetLaceType(DMC64Image *img, const DMC64EncDecOp *op,
177 const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 178 const DMGrowBuf *buf, const DMC64ImageFormat *fmt)
178 { 179 {
179 (void) len;
180 (void) fmt; 180 (void) fmt;
181 img->laceType = buf[op->offs] ? D64_ILACE_RES : D64_ILACE_COLOR; 181 img->laceType = buf->data[op->offs] ? D64_ILACE_RES : D64_ILACE_COLOR;
182 return TRUE; 182 return TRUE;
183 } 183 }
184 184
185 185
186 static BOOL fmtDrazLaceSetLaceType(const DMC64EncDecOp *op, DMGrowBuf *buf, 186 static BOOL fmtDrazLaceSetLaceType(const DMC64EncDecOp *op, DMGrowBuf *buf,
203 203
204 return DM_PROBE_SCORE_FALSE; 204 return DM_PROBE_SCORE_FALSE;
205 } 205 }
206 206
207 207
208 static int fmtDecodeBDP5Packed(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 208 static int fmtDecodeBDP5Packed(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt)
209 {
210 int res;
211 DMGrowBuf mem, tmp;
212 DMCompParams cfg;
213
214 cfg.type = DM_COMP_RLE_MARKER;
215 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_WORD_RUNS | DM_RLE_ORDER_1;
216 cfg.rleMarkerB = buf->data[8];
217 cfg.rleMarkerW = buf->data[9];
218
219 if ((res = dmDecodeGenericRLEAlloc(&mem,
220 dmGrowBufCreateFromOffs(&tmp, buf, 10), &cfg)) != DMERR_OK)
221 goto out;
222
223 res = dmC64DecodeGenericBMP(img, &mem, fmt);
224
225 out:
226 dmGrowBufFree(&mem);
227 return res;
228 }
229
230
231 static int fmtEncodeBDP5Packed(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt)
209 { 232 {
210 int res; 233 int res;
211 DMGrowBuf mem; 234 DMGrowBuf mem;
212 DMCompParams cfg; 235 DMCompParams cfg;
213 236
214 cfg.type = DM_COMP_RLE_MARKER;
215 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_WORD_RUNS | DM_RLE_ORDER_1;
216 cfg.rleMarkerB = buf[8];
217 cfg.rleMarkerW = buf[9];
218
219 if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 10, buf + len, &cfg)) != DMERR_OK)
220 goto out;
221
222 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt);
223
224 out:
225 dmGrowBufFree(&mem);
226 return res;
227 }
228
229
230 static int fmtEncodeBDP5Packed(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt)
231 {
232 int res;
233 DMGrowBuf tmp;
234 DMCompParams cfg;
235
236 // Encode the data to temp buffer 237 // Encode the data to temp buffer
237 if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) 238 if ((res = dmC64EncodeGenericBMP(TRUE, &mem, img, fmt)) != DMERR_OK)
238 goto out; 239 goto out;
239 240
240 // Analyze and setup RLE 241 // Analyze and setup RLE
241 cfg.type = DM_COMP_RLE_MARKER; 242 cfg.type = DM_COMP_RLE_MARKER;
242 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_WORD_RUNS | DM_RLE_ORDER_1; 243 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_WORD_RUNS | DM_RLE_ORDER_1;
243 cfg.rleMinCountB = 3; 244 cfg.rleMinCountB = 3;
244 cfg.rleMaxCountB = 255; 245 cfg.rleMaxCountB = 255;
245 cfg.rleMinCountW = 256; 246 cfg.rleMinCountW = 256;
246 cfg.rleMaxCountW = 1024; 247 cfg.rleMaxCountW = 1024;
247 248
248 dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); 249 dmGenericRLEAnalyze(&mem, &cfg);
249 250
250 // Add the header bits 251 // Add the header bits
251 if (!dmGrowBufPut(buf, (Uint8 *) fmtBDP5MagicID, strlen(fmtBDP5MagicID)) || 252 if (!dmGrowBufPut(buf, (Uint8 *) fmtBDP5MagicID, strlen(fmtBDP5MagicID)) ||
252 !dmGrowBufPutU8(buf, cfg.rleMarkerB) || 253 !dmGrowBufPutU8(buf, cfg.rleMarkerB) ||
253 !dmGrowBufPutU8(buf, cfg.rleMarkerW)) 254 !dmGrowBufPutU8(buf, cfg.rleMarkerW))
255 res = DMERR_MALLOC; 256 res = DMERR_MALLOC;
256 goto out; 257 goto out;
257 } 258 }
258 259
259 // And now RLE compress the data to the existing buffer 260 // And now RLE compress the data to the existing buffer
260 res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); 261 res = dmEncodeGenericRLE(buf, &mem, &cfg);
261 262
262 out: 263 out:
263 dmGrowBufFree(&tmp); 264 dmGrowBufFree(&mem);
264 return res; 265 return res;
265 } 266 }
266 267
267 268
268 static int fmtProbeGunPaint(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 269 static int fmtProbeGunPaint(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
300 301
301 return DM_PROBE_SCORE_FALSE; 302 return DM_PROBE_SCORE_FALSE;
302 } 303 }
303 304
304 305
305 static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 306 static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt)
306 { 307 {
307 int res; 308 int res;
308 DMGrowBuf mem, tmp; 309 DMGrowBuf mem, tmp;
309 DMCompParams cfg; 310 DMCompParams cfg;
310 311
311 // Amica Paint apparently is broken and stores one byte less than it should 312 // Amica Paint apparently is broken and stores one byte less than it should
312 // so we need to do some crappy buffer expansion here .. 313 // so we need to do some crappy buffer expansion here ..
313 if ((res = dmGrowBufAlloc(&tmp, len + 4, 4)) != DMERR_OK) 314 if ((res = dmGrowBufAlloc(&tmp, buf->len + 4, 4)) != DMERR_OK)
314 return res; 315 return res;
315 316
316 memcpy(tmp.data, buf, len); 317 memcpy(tmp.data, buf->data, buf->len);
317 tmp.len = len + 1; 318 tmp.len = buf->len + 1;
318 319
319 // Now do an RLE decode on the enlarged buffer 320 // Now do an RLE decode on the enlarged buffer
320 cfg.type = DM_COMP_RLE_MARKER; 321 cfg.type = DM_COMP_RLE_MARKER;
321 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; 322 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1;
322 cfg.rleMarkerB = 0xC2; 323 cfg.rleMarkerB = 0xC2;
323 324
324 if ((res = dmDecodeGenericRLEAlloc(&mem, tmp.data, tmp.data + tmp.len, &cfg)) != DMERR_OK) 325 if ((res = dmDecodeGenericRLEAlloc(&mem, &tmp, &cfg)) != DMERR_OK)
325 goto out; 326 goto out;
326 327
327 // And finally decode to bitmap struct 328 // And finally decode to bitmap struct
328 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); 329 res = dmC64DecodeGenericBMP(img, &mem, fmt);
329 330
330 out: 331 out:
331 dmGrowBufFree(&tmp); 332 dmGrowBufFree(&tmp);
332 dmGrowBufFree(&mem); 333 dmGrowBufFree(&mem);
333 return res; 334 return res;
335 336
336 337
337 static int fmtEncodeAmicaPaintPacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) 338 static int fmtEncodeAmicaPaintPacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt)
338 { 339 {
339 int res; 340 int res;
340 DMGrowBuf tmp; 341 DMGrowBuf mem;
341 DMCompParams cfg; 342 DMCompParams cfg;
342 343
343 // Encode the data to temp buffer 344 // Encode the data to temp buffer
344 if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) 345 if ((res = dmC64EncodeGenericBMP(TRUE, &mem, img, fmt)) != DMERR_OK)
345 goto out; 346 goto out;
346 347
347 // And now RLE compress the data to the existing buffer 348 // And now RLE compress the data to the existing buffer
348 cfg.type = DM_COMP_RLE_MARKER; 349 cfg.type = DM_COMP_RLE_MARKER;
349 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; 350 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1;
350 cfg.rleMarkerB = 0xC2; 351 cfg.rleMarkerB = 0xC2;
351 cfg.rleMinCountB = 3; 352 cfg.rleMinCountB = 3;
352 cfg.rleMaxCountB = 255; 353 cfg.rleMaxCountB = 255;
353 354
354 res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); 355 res = dmEncodeGenericRLE(buf, &mem, &cfg);
355 356
356 out: 357 out:
357 dmGrowBufFree(&tmp); 358 dmGrowBufFree(&mem);
358 return res; 359 return res;
359 } 360 }
360 361
361 362
362 static int fmtProbeFLIDesigner(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 363 static int fmtProbeFLIDesigner(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
368 return DM_PROBE_SCORE_FALSE; 369 return DM_PROBE_SCORE_FALSE;
369 } 370 }
370 371
371 372
372 static BOOL fmtTruePaintGetLaceType(DMC64Image *img, const DMC64EncDecOp *op, 373 static BOOL fmtTruePaintGetLaceType(DMC64Image *img, const DMC64EncDecOp *op,
373 const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 374 const DMGrowBuf *buf, const DMC64ImageFormat *fmt)
374 { 375 {
375 (void) op; 376 (void) op;
376 (void) buf; 377 (void) buf;
377 (void) len;
378 (void) fmt; 378 (void) fmt;
379 img->laceType = D64_ILACE_RES; 379 img->laceType = D64_ILACE_RES;
380 return TRUE; 380 return TRUE;
381 } 381 }
382 382
425 else 425 else
426 return TRUE; 426 return TRUE;
427 } 427 }
428 428
429 429
430 static int fmtDecodeTruePaintPacked(DMC64Image *img, const Uint8 *src, const size_t srcLen, const DMC64ImageFormat *fmt) 430 static int fmtDecodeTruePaintPacked(DMC64Image *img, const DMGrowBuf *src, const DMC64ImageFormat *fmt)
431 { 431 {
432 int res = DMERR_OK; 432 int res = DMERR_OK;
433 Uint8 *dst = NULL; 433 Uint8 *dst = NULL;
434 DMGrowBuf dstTmp;
434 const Uint8 *codeBook1, *codeBook2; 435 const Uint8 *codeBook1, *codeBook2;
435 size_t 436 size_t
436 srcOffs, dstOffs, 437 srcOffs, dstOffs,
437 dstLen = 0x4be8; 438 dstLen = 0x4be8;
438 // 1b7e-67e8 decoded by original depacker 439 // 1b7e-67e8 decoded by original depacker
439 // 1c00-67e8 is the actual area used tho 440 // 1c00-67e8 is the actual area used tho
440 441
441 // Codebooks: #1 is trampoline table markers, #2 is RLE data table 442 // Codebooks: #1 is trampoline table markers, #2 is RLE data table
442 codeBook1 = src + 0x81 - 2; 443 codeBook1 = src->data + 0x81 - 2;
443 codeBook2 = src + 0x85 - 2; 444 codeBook2 = src->data + 0x85 - 2;
444 445
445 // Allocate output buffer 446 // Allocate output buffer
446 if ((dst = dmMalloc0(dstLen)) == NULL) 447 if ((dst = dmMalloc0(dstLen)) == NULL)
447 { 448 {
448 res = dmError(DMERR_MALLOC, 449 res = dmError(DMERR_MALLOC,
449 "Could not allocate memory for temporary decompression buffer.\n"); 450 "Could not allocate memory for temporary decompression buffer.\n");
450 goto out; 451 goto out;
451 } 452 }
452 453
453 // Begin decompression 454 // Begin decompression
454 srcOffs = srcLen; 455 srcOffs = src->len;
455 dstOffs = dstLen; 456 dstOffs = dstLen;
456 457
457 while (srcOffs > 0 && dstOffs > 0) 458 while (srcOffs > 0 && dstOffs > 0)
458 { 459 {
459 Uint8 data; 460 Uint8 data;
460 int count = 1, scount; 461 int count = 1, scount;
461 BOOL found = FALSE; 462 BOOL found = FALSE;
462 463
463 if (!fmtTruePaintGetByte(src, &srcOffs, &data, &res, -1)) 464 if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, -1))
464 goto out; 465 goto out;
465 466
466 for (int n = 0; n < 8; n++) 467 for (int n = 0; n < 8; n++)
467 if (codeBook1[n] == data && !found) 468 if (codeBook1[n] == data && !found)
468 { 469 {
469 found = TRUE; 470 found = TRUE;
470 switch (n) 471 switch (n)
471 { 472 {
472 case 4: // Y = 4, JTO = $0B 473 case 4: // Y = 4, JTO = $0B
473 if (!fmtTruePaintGetByte(src, &srcOffs, &data, &res, n)) 474 if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, n))
474 goto out; 475 goto out;
475 476
476 count = data; 477 count = data;
477 if (data == 0) 478 if (data == 0)
478 goto finish; 479 goto finish;
482 case 1: // Y = 1, JTO = $17 483 case 1: // Y = 1, JTO = $17
483 count += 2; 484 count += 2;
484 // fallthrough 485 // fallthrough
485 486
486 case 0: // Y = 0, JTO = $19 487 case 0: // Y = 0, JTO = $19
487 if (!fmtTruePaintGetByte(src, &srcOffs, &data, &res, n)) 488 if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, n))
488 goto out; 489 goto out;
489 break; 490 break;
490 491
491 case 2: // Y = 2, JTO = $07 492 case 2: // Y = 2, JTO = $07
492 if (!fmtTruePaintGetByte(src, &srcOffs, &data, &res, n)) 493 if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, n))
493 goto out; 494 goto out;
494 495
495 count = data; 496 count = data;
496 // fallthrough 497 // fallthrough
497 498
518 } 519 }
519 } 520 }
520 } 521 }
521 522
522 finish: 523 finish:
523 res = dmC64DecodeGenericBMP(img, dst, dstLen, fmt); 524 res = dmC64DecodeGenericBMP(img, dmGrowBufCreateFrom(&dstTmp, dst, dstLen), fmt);
524 525
525 out: 526 out:
526 dmFree(dst); 527 dmFree(dst);
527 return res; 528 return res;
528 } 529 }
543 544
544 return DM_PROBE_SCORE_FALSE; 545 return DM_PROBE_SCORE_FALSE;
545 } 546 }
546 547
547 548
548 static int fmtDecodeFormatXX2(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 549 static int fmtDecodeFormatXX2(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt)
549 { 550 {
550 int res; 551 int res;
552 DMGrowBuf tmp;
551 553
552 // If there is only data for less than XX2_MIN_SIZE bytes, 554 // If there is only data for less than XX2_MIN_SIZE bytes,
553 // allocate a buffer of that size and copy data there. 555 // allocate a buffer of that size and copy data there.
554 // Otherwise allocate len bytes. 556 // Otherwise allocate len bytes.
555 size_t nlen = len < XX2_MIN_SIZE ? XX2_MIN_SIZE : len; 557 size_t nlen = buf->len < XX2_MIN_SIZE ? XX2_MIN_SIZE : buf->len;
556 Uint8 *mem = dmMalloc0(nlen); 558 Uint8 *mem = dmMalloc0(nlen);
557 if (mem == NULL) 559 if (mem == NULL)
558 return DMERR_MALLOC; 560 return DMERR_MALLOC;
559 561
560 memcpy(mem, buf, len); 562 memcpy(mem, buf->data, buf->len);
561 res = dmC64DecodeGenericBMP(img, mem, nlen, fmt); 563 res = dmC64DecodeGenericBMP(img, dmGrowBufCreateFrom(&tmp, mem, nlen), fmt);
562 564
563 dmFree(mem); 565 dmFree(mem);
564 return res; 566 return res;
565 } 567 }
566 568
578 else 580 else
579 return DM_PROBE_SCORE_FALSE; 581 return DM_PROBE_SCORE_FALSE;
580 } 582 }
581 583
582 584
583 static int fmtDecodeFunPaint2(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 585 static int fmtDecodeFunPaint2(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt)
584 { 586 {
585 int res; 587 int res;
588 DMGrowBuf tmp;
586 589
587 // Check if the data is compressed 590 // Check if the data is compressed
588 if (buf[14]) 591 if (buf->data[14])
589 { 592 {
590 DMGrowBuf mem; 593 DMGrowBuf mem;
591 DMCompParams cfg; 594 DMCompParams cfg;
592 595
593 cfg.type = DM_COMP_RLE_MARKER; 596 cfg.type = DM_COMP_RLE_MARKER;
594 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; 597 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1;
595 cfg.rleMarkerB = buf[15]; 598 cfg.rleMarkerB = buf->data[15];
596 599
597 if ((res = dmDecodeGenericRLEAlloc( 600 if ((res = dmDecodeGenericRLEAlloc(
598 &mem, buf + FUNPAINT2_HEADER_SIZE, buf + len, &cfg)) == DMERR_OK) 601 &mem, dmGrowBufCreateFromOffs(&tmp, buf, FUNPAINT2_HEADER_SIZE), &cfg)) == DMERR_OK)
599 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); 602 res = dmC64DecodeGenericBMP(img, &mem, fmt);
600 603
601 dmGrowBufFree(&mem); 604 dmGrowBufFree(&mem);
602 } 605 }
603 else 606 else
604 { 607 {
605 res = dmC64DecodeGenericBMP(img, buf + FUNPAINT2_HEADER_SIZE, len - FUNPAINT2_HEADER_SIZE, fmt); 608 res = dmC64DecodeGenericBMP(img, dmGrowBufCreateFromOffs(&tmp, buf, FUNPAINT2_HEADER_SIZE), fmt);
606 } 609 }
607 610
608 return res; 611 return res;
609 } 612 }
610 613
621 624
622 625
623 static int fmtEncodeFunPaint2Packed(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) 626 static int fmtEncodeFunPaint2Packed(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt)
624 { 627 {
625 int res; 628 int res;
626 DMGrowBuf tmp; 629 DMGrowBuf mem;
627 DMCompParams cfg; 630 DMCompParams cfg;
628 631
629 // Encode the data to temp buffer 632 // Encode the data to temp buffer
630 if ((res = dmC64EncodeGenericBMP(TRUE, &tmp, img, fmt)) != DMERR_OK) 633 if ((res = dmC64EncodeGenericBMP(TRUE, &mem, img, fmt)) != DMERR_OK)
631 goto out; 634 goto out;
632 635
633 // Analyze and setup RLE 636 // Analyze and setup RLE
634 cfg.type = DM_COMP_RLE_MARKER; 637 cfg.type = DM_COMP_RLE_MARKER;
635 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; 638 cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1;
636 cfg.rleMinCountB = 3; 639 cfg.rleMinCountB = 3;
637 cfg.rleMaxCountB = 255; 640 cfg.rleMaxCountB = 255;
638 641
639 dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); 642 dmGenericRLEAnalyze(&mem, &cfg);
640 643
641 // Add the header bits 644 // Add the header bits
642 if (!dmGrowBufPut(buf, (Uint8 *) fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) || 645 if (!dmGrowBufPut(buf, (Uint8 *) fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) ||
643 !dmGrowBufPutU8(buf, cfg.rleMarkerB)) 646 !dmGrowBufPutU8(buf, cfg.rleMarkerB))
644 { 647 {
645 res = DMERR_MALLOC; 648 res = DMERR_MALLOC;
646 goto out; 649 goto out;
647 } 650 }
648 651
649 // And now RLE compress the data to the existing buffer 652 // And now RLE compress the data to the existing buffer
650 res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); 653 res = dmEncodeGenericRLE(buf, &mem, &cfg);
651 654
652 out: 655 out:
653 dmGrowBufFree(&tmp); 656 dmGrowBufFree(&mem);
654 return res; 657 return res;
655 } 658 }
656 659
657 660
658 static Uint8 fmtGetPixelFunPaint2( 661 static Uint8 fmtGetPixelFunPaint2(
1171 { 1174 {
1172 { DO_COPY , DS_BITMAP_RAM , 0x0000, 0, 0, NULL, NULL }, 1175 { DO_COPY , DS_BITMAP_RAM , 0x0000, 0, 0, NULL, NULL },
1173 { DO_COPY , DS_SCREEN_RAM , 0x2000, 0, 0, NULL, NULL }, 1176 { DO_COPY , DS_SCREEN_RAM , 0x2000, 0, 0, NULL, NULL },
1174 { DO_COPY , DS_COLOR_RAM , 0x2400, 0, 0, NULL, NULL }, 1177 { DO_COPY , DS_COLOR_RAM , 0x2400, 0, 0, NULL, NULL },
1175 { DO_SET_OP , DS_BGCOL , 0x00 , 0, 0, NULL, NULL }, 1178 { DO_SET_OP , DS_BGCOL , 0x00 , 0, 0, NULL, NULL },
1179 { DO_SET_OP , DS_EXTRA_DATA , 10240 , 0, 0, NULL, NULL },
1176 { DO_LAST , 0 , 0 , 0, 0, NULL, NULL }, 1180 { DO_LAST , 0 , 0 , 0, 0, NULL, NULL },
1177 }, 1181 },
1178 NULL 1182 NULL
1179 }, 1183 },
1180 1184