comparison tools/lib64fmts.c @ 2525:19b0ca169361

Implement SupeRes encoding.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 15 May 2020 07:44:12 +0300
parents 5a7e2aa8fef5
children 4deb8da6c901
comparison
equal deleted inserted replaced
2524:5a7e2aa8fef5 2525:19b0ca169361
256 dmGrowBufConstCreateFrom(&tmp, ctx.dstBuf, ctx.dstSize), fmt); 256 dmGrowBufConstCreateFrom(&tmp, ctx.dstBuf, ctx.dstSize), fmt);
257 257
258 out: 258 out:
259 dmFree(ctx.dstBuf); 259 dmFree(ctx.dstBuf);
260 return res; 260 return res;
261 }
262
263
264 typedef struct
265 {
266 DMGrowBuf *buf;
267
268 int cnt1, cnt2, dbyte;
269 } DMSupeResEncCtx;
270
271
272 static BOOL fmtEncodeSupeResRun(DMSupeResEncCtx *ctx)
273 {
274 if (ctx->cnt2 == 255)
275 ctx->cnt2 = 0x24;
276 else
277 if (ctx->cnt2 > 216)
278 {
279 if (!dmGrowBufPutU8(ctx->buf, 0x25))
280 return FALSE;
281 }
282 else
283 ctx->cnt2 += 0x26;
284
285 if (!dmGrowBufPutU8(ctx->buf, ctx->cnt2))
286 return FALSE;
287
288 ctx->cnt1 = ctx->cnt2 = 0;
289
290 return TRUE;
291 }
292
293
294 static BOOL fmtEncodeSupeResFlush(DMSupeResEncCtx *ctx)
295 {
296 ctx->cnt1 += 0x26;
297
298 if (!dmGrowBufPutU8(ctx->buf, 0x20) ||
299 !dmGrowBufPutU8(ctx->buf, ctx->cnt1))
300 return FALSE;
301
302 return fmtEncodeSupeResRun(ctx);
303 }
304
305
306 static BOOL fmtEncodeSupeResSection(DMSupeResEncCtx *ctx, const DMC64MemBlock *blk)
307 {
308 for (size_t offs = 0; offs < blk->size; offs++)
309 {
310 ctx->dbyte = blk->data[offs];
311
312 if ((ctx->cnt1 == 0 && offs + 1 < blk->size && ctx->dbyte == blk->data[offs + 1]) ||
313 (ctx->cnt1 != 0 && ctx->dbyte == ctx->cnt2))
314 {
315 ctx->cnt1++;
316 ctx->cnt2 = ctx->dbyte;
317
318 if (ctx->cnt1 >= 215 &&
319 !fmtEncodeSupeResFlush(ctx))
320 return FALSE;
321
322 continue;
323 }
324 else
325 if (ctx->cnt1 != 0 && ctx->dbyte != ctx->cnt2)
326 {
327 if (!fmtEncodeSupeResFlush(ctx))
328 return FALSE;
329 }
330
331 ctx->cnt2 = ctx->dbyte;
332
333 if (!fmtEncodeSupeResRun(ctx))
334 return FALSE;
335 }
336
337 if (ctx->cnt1 > 0)
338 return fmtEncodeSupeResFlush(ctx);
339
340 return TRUE;
341 }
342
343
344 static int fmtEncodeSupeRes(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt)
345 {
346 DMSupeResEncCtx ctx;
347 BOOL bres;
348
349 // Output magic header and data type
350 if (!dmGrowBufPut(buf, fmtSupeRes_MagicID_1, sizeof(fmtSupeRes_MagicID_1)) ||
351 !dmGrowBufPutU8(buf, fmt->extra))
352 {
353 return dmError(DMERR_MALLOC,
354 "Error outputting SupeRes magic header.\n");
355 }
356
357 memset(&ctx, 0, sizeof(ctx));
358 ctx.buf = buf;
359
360 switch (fmt->extra)
361 {
362 case 0x23:
363 case 0x25:
364 bres =
365 fmtEncodeSupeResSection(&ctx, &img->screen[0]) &&
366 fmtEncodeSupeResSection(&ctx, &img->bitmap[0]);
367 break;
368
369 case 0x24:
370 case 0x26:
371 ctx.cnt2 = img->bgcolor;
372 bres =
373 fmtEncodeSupeResRun(&ctx) &&
374 fmtEncodeSupeResSection(&ctx, &img->screen[0]) &&
375 fmtEncodeSupeResSection(&ctx, &img->color[0]) &&
376 fmtEncodeSupeResSection(&ctx, &img->bitmap[0]);
377 break;
378 }
379
380 return bres ? DMERR_OK : DMERR_MALLOC;
261 } 381 }
262 382
263 383
264 static const Uint8 fmtMarqPETSCII_ID1[] = 384 static const Uint8 fmtMarqPETSCII_ID1[] =
265 { 385 {
3070 }, 3190 },
3071 NULL 3191 NULL
3072 }, 3192 },
3073 3193
3074 { 3194 {
3075 "suphi1", "SupeRes hires [clear] (packed)", -1, 0, 0x23, DM_FMT_RD, 3195 "suphi1", "SupeRes hires [clear] (packed)", -1, 0, 0x23, DM_FMT_RDWR,
3076 fmtProbeSupeRes, 3196 fmtProbeSupeRes,
3077 fmtDecodeSupeRes, NULL, 3197 fmtDecodeSupeRes,fmtEncodeSupeRes,
3078 { }, &dmC64CommonFormats[10] 3198 { }, &dmC64CommonFormats[10]
3079 }, 3199 },
3080 3200
3081 { 3201 {
3082 "suphi2", "SupeRes hires [no-clear] (packed)", -1, 0, 0x25, DM_FMT_RD, 3202 "suphi2", "SupeRes hires [no-clear] (packed)", -1, 0, 0x25, DM_FMT_RDWR,
3083 fmtProbeSupeRes, 3203 fmtProbeSupeRes,
3084 fmtDecodeSupeRes, NULL, 3204 fmtDecodeSupeRes,fmtEncodeSupeRes,
3085 { }, &dmC64CommonFormats[10] 3205 { }, &dmC64CommonFormats[10]
3086 }, 3206 },
3087 3207
3088 { 3208 {
3089 "supmc1", "SupeRes multicolor [clear] (packed)", -1, 0, 0x24, DM_FMT_RD, 3209 "supmc1", "SupeRes multicolor [clear] (packed)", -1, 0, 0x24, DM_FMT_RDWR,
3090 fmtProbeSupeRes, 3210 fmtProbeSupeRes,
3091 fmtDecodeSupeRes, NULL, 3211 fmtDecodeSupeRes,fmtEncodeSupeRes,
3092 { }, &dmC64CommonFormats[0] 3212 { }, &dmC64CommonFormats[0]
3093 }, 3213 },
3094 3214
3095 { 3215 {
3096 "supmc2", "SupeRes multicolor [no-clear] (packed)", -1, 0, 0x26, DM_FMT_RD, 3216 "supmc2", "SupeRes multicolor [no-clear] (packed)", -1, 0, 0x26, DM_FMT_RDWR,
3097 fmtProbeSupeRes, 3217 fmtProbeSupeRes,
3098 fmtDecodeSupeRes, NULL, 3218 fmtDecodeSupeRes,fmtEncodeSupeRes,
3099 { }, &dmC64CommonFormats[0] 3219 { }, &dmC64CommonFormats[0]
3100 }, 3220 },
3101 }; 3221 };
3102 3222
3103 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]); 3223 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]);