comparison tools/lib64gfx.c @ 1478:d883b4c1cf48

More work on RLE encoding/decoding.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 11 May 2018 02:42:49 +0300
parents f0232684857a
children df6dacb48970
comparison
equal deleted inserted replaced
1477:e8fe529f4341 1478:d883b4c1cf48
287 err: 287 err:
288 return res; 288 return res;
289 } 289 }
290 290
291 291
292 static int dmDecodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd,
293 const Uint8 rleMarker, const Uint8 rleMask1, const Uint8 rleMask2, const int rleType)
294 {
295 int res;
296 if ((res = dmGrowBufAlloc(dst, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK)
297 return res;
298
299 return dmDecodeGenericRLE(dst, src, srcEnd, rleMarker, rleMask1, rleMask2, rleType);
300 }
301
302
303 static BOOL dmEncodeGenericRLESequence(DMGrowBuf *dst, const Uint8 data, const Uint8 count, const Uint8 rleMarker, const int rleType)
304 {
305 switch (rleType)
306 {
307 case DM_RLE_MARKER:
308 // A simple marker byte RLE variant: [Marker] [count] [data]
309 if (!dmGrowBufPutU8(dst, rleMarker) ||
310 !dmGrowBufPutU8(dst, count) ||
311 !dmGrowBufPutU8(dst, data))
312 return FALSE;
313 break;
314
315 case DM_RLE_MASK:
316 // Mask marker RLE: usually high bit(s) of byte mark RLE sequence
317 // and the lower bits contain the count: [Mask + count] [data]
318 if (!dmGrowBufPutU8(dst, rleMarker | count) ||
319 !dmGrowBufPutU8(dst, data))
320 return FALSE;
321 break;
322 }
323
324 return TRUE;
325 }
326
327
292 static int dmEncodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, 328 static int dmEncodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd,
293 const Uint8 rleMarker, const Uint8 rleMask1, const Uint8 rleMask2, const int rleType) 329 const Uint8 rleMarker, const Uint8 rleMinCount, const Uint8 rleMaxCount, const int rleType)
294 { 330 {
295 (void) dst; 331 int res;
296 (void) src; 332
297 (void) srcEnd; 333 // Perform RLE encoding
298 (void) rleMarker; 334 int count = 0, prev;
299 (void) rleMask1; 335 while (src < srcEnd)
300 (void) rleMask2; 336 {
301 (void) rleType; 337 Uint8 data = *src++;
302 338
303 return DMERR_OK; 339 if ((count >= rleMinCount && data != prev) || count >= rleMaxCount)
340 {
341 if (!dmEncodeGenericRLESequence(dst, prev, count + 1, rleMarker, rleType))
342 {
343 res = dmError(DMERR_MALLOC,
344 "Could reallocate memory for RLE encoding buffer.\n");
345 goto err;
346 }
347
348 count = 1;
349 }
350
351 prev = data;
352 }
353
354 res = DMERR_OK;
355
356 err:
357 return res;
358 }
359
360
361 static int dmEncodeGenericRLEAlloc(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd,
362 const Uint8 rleMarker, const Uint8 rleMinCount, const Uint8 rleMaxCount, const int rleType)
363 {
364 int res;
365 if ((res = dmGrowBufAlloc(dst, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK)
366 return res;
367
368 return dmEncodeGenericRLE(dst, src, srcEnd, rleMarker, rleMinCount, rleMaxCount, rleType);
304 } 369 }
305 370
306 371
307 static inline Uint8 dmC64GetGenericSCPixel( 372 static inline Uint8 dmC64GetGenericSCPixel(
308 const DMC64Image *img, const int bmoffs, const int scroffs, 373 const DMC64Image *img, const int bmoffs, const int scroffs,
368 static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 433 static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
369 { 434 {
370 int res; 435 int res;
371 DMGrowBuf mem; 436 DMGrowBuf mem;
372 437
373 if ((res = dmDecodeGenericRLE(&mem, buf + 0x0e, buf + len, *(buf + 0x0d), 0, 0, DM_RLE_MARKER)) != DMERR_OK) 438 if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 0x0e, buf + len, *(buf + 0x0d), 0, 0, DM_RLE_MARKER)) != DMERR_OK)
374 goto out; 439 goto out;
375 440
376 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); 441 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt);
377 442
378 out: 443 out: