Mercurial > hg > dmlib
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 |