Mercurial > hg > dmlib
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]); |