comparison tools/lib64fmts.c @ 2519:4dbb6572622d

Add preliminary decoder for SupeRes hires and multicolor files. The decoder is pretty horrible at the moment, should be cleaned up.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 15 May 2020 02:46:53 +0300
parents 09082816665d
children b19535da15e9
comparison
equal deleted inserted replaced
2518:470631c00c97 2519:4dbb6572622d
58 58
59 memcpy(buf->data + 2, fmtMicroIllustrator_MagicID_1, sizeof(fmtMicroIllustrator_MagicID_1)); 59 memcpy(buf->data + 2, fmtMicroIllustrator_MagicID_1, sizeof(fmtMicroIllustrator_MagicID_1));
60 memcpy(buf->data + 9, fmtMicroIllustrator_MagicID_2, sizeof(fmtMicroIllustrator_MagicID_2)); 60 memcpy(buf->data + 9, fmtMicroIllustrator_MagicID_2, sizeof(fmtMicroIllustrator_MagicID_2));
61 61
62 return DMERR_OK; 62 return DMERR_OK;
63 }
64
65
66 static const Uint8 fmtSupeRes_MagicID_1[] =
67 {
68 0x40, 0x5c, 0x2a,
69 };
70
71
72 static int fmtProbeSupeRes(const DMGrowBuf *buf, const DMC64ImageFormat *fmt)
73 {
74 if (buf->len > 12 &&
75 DM_MEMCMP_SIZE(buf->data, fmtSupeRes_MagicID_1) == 0)
76 {
77 if (buf->data[3] == fmt->size)
78 return DM_PROBE_SCORE_MAX;
79 }
80
81 return DM_PROBE_SCORE_FALSE;
82 }
83
84
85 typedef struct
86 {
87 DMGrowBuf src;
88 Uint8 *dstBuf;
89 size_t dstSize;
90
91 Uint8 dbyte, repcount;
92
93 size_t offs, end_offs;
94 } DMSupeResCtx;
95
96
97 static int fmtSupeResGetByte(DMSupeResCtx *ctx, Uint8 *data, const int mode)
98 {
99 if (!dmGrowBufGetU8(&ctx->src, data))
100 {
101 return dmError(DMERR_INVALID_DATA,
102 "SupeRes: Out of input data (N=%d).\n",
103 mode);
104 }
105 else
106 {
107 return DMERR_OK;
108 }
109 }
110
111
112 static int fmtDecodeSupeResByte(DMSupeResCtx *ctx)
113 {
114 Uint8 tmp;
115 int res;
116
117 lcont:
118
119 if ((res = fmtSupeResGetByte(ctx, &tmp, 1)) != DMERR_OK)
120 goto out;
121
122 if (tmp == 0x21)
123 {
124 // ????
125 ctx->offs = 0xffff;
126 return DMERR_OK;
127 }
128 else
129 if (tmp == 0x24)
130 {
131 ctx->dbyte = 0xff;
132 return DMERR_OK;
133 }
134 else
135 if (tmp == 0x20)
136 {
137 if ((res = fmtSupeResGetByte(ctx, &tmp, 2)) != DMERR_OK)
138 goto out;
139
140 ctx->repcount = tmp - 0x26;
141
142 if ((res = fmtSupeResGetByte(ctx, &tmp, 3)) != DMERR_OK)
143 goto out;
144
145 if (tmp == 0x24)
146 {
147 ctx->dbyte = 0xff;
148 }
149 else
150 {
151 if (tmp == 0x25)
152 {
153 if ((res = fmtSupeResGetByte(ctx, &tmp, 4)) != DMERR_OK)
154 goto out;
155
156 tmp = (0x26 + tmp) & 0xff;
157 }
158
159 ctx->dbyte = tmp - 0x26;
160 }
161
162 for (int cnt = 0; cnt < ctx->repcount; cnt++)
163 {
164 ctx->dstBuf[ctx->offs++] = ctx->dbyte;
165 if (ctx->offs >= ctx->end_offs)
166 goto out;
167 }
168
169 if (ctx->offs < ctx->end_offs)
170 goto lcont;
171
172 ctx->offs--;
173
174 goto out;
175 }
176 else
177 {
178 if (tmp == 0x25)
179 {
180 if ((res = fmtSupeResGetByte(ctx, &tmp, 9)) != DMERR_OK)
181 goto out;
182
183 tmp = (0x26 + tmp) & 0xff;
184 }
185
186 ctx->dbyte = tmp - 0x26;
187
188 return DMERR_OK;
189 }
190
191 goto lcont;
192
193 out:
194 return res;
195 }
196
197
198 static int fmtDecodeSupeResSection(DMSupeResCtx *ctx, const size_t offs, const size_t size)
199 {
200 int res = DMERR_OK;
201
202 ctx->offs = offs;
203 ctx->end_offs = offs + size;
204
205 do
206 {
207 if ((res = fmtDecodeSupeResByte(ctx)) != DMERR_OK)
208 goto out;
209
210 if (ctx->offs < ctx->end_offs)
211 ctx->dstBuf[ctx->offs++] = ctx->dbyte;
212
213 } while (ctx->offs < ctx->end_offs);
214
215 out:
216 return res;
217 }
218
219
220 static int fmtDecodeSupeRes(DMC64Image *img, const DMGrowBuf *psrc, const DMC64ImageFormat *fmt)
221 {
222 DMSupeResCtx ctx;
223 DMGrowBuf tmp;
224 int res;
225
226 memset(&ctx, 0, sizeof(ctx));
227 ctx.dstSize = 0x4000;
228
229 // As we need to modify the offs, etc. but not the data,
230 // we will just make a shallow copy of the DMGrowBuf struct
231 dmGrowBufConstCopyOffs(&ctx.src, psrc, 4);
232
233 // Allocate output buffer
234 if ((ctx.dstBuf = dmMalloc0(ctx.dstSize)) == NULL)
235 {
236 return dmError(DMERR_MALLOC,
237 "Could not allocate memory for decoding buffer.\n");
238 }
239
240 switch (fmt->size)
241 {
242 case 0x23:
243 case 0x25:
244 if ((res = fmtDecodeSupeResSection(&ctx, 0x0000, 0x03e8)) != DMERR_OK ||
245 (res = fmtDecodeSupeResSection(&ctx, 0x0400, 0x1f40)) != DMERR_OK)
246 goto out;
247 break;
248
249 case 0x24:
250 case 0x26:
251 if ((res = fmtDecodeSupeResByte (&ctx)) != DMERR_OK)
252 goto out;
253
254 ctx.dstBuf[0x2710] = ctx.dbyte;
255
256 if ((res = fmtDecodeSupeResSection(&ctx, 0x1f40, 0x03e8)) != DMERR_OK ||
257 (res = fmtDecodeSupeResSection(&ctx, 0x2328, 0x03e8)) != DMERR_OK ||
258 (res = fmtDecodeSupeResSection(&ctx, 0x0000, 0x1f40)) != DMERR_OK)
259 goto out;
260
261 break;
262 }
263
264 res = dmC64DecodeGenericBMP(img,
265 dmGrowBufConstCreateFrom(&tmp, ctx.dstBuf, ctx.dstSize), fmt);
266
267 out:
268 dmFree(ctx.dstBuf);
269 return res;
63 } 270 }
64 271
65 272
66 static const Uint8 fmtMarqPETSCII_ID1[] = 273 static const Uint8 fmtMarqPETSCII_ID1[] =
67 { 274 {
2872 } 3079 }
2873 }, 3080 },
2874 NULL 3081 NULL
2875 }, 3082 },
2876 3083
3084 {
3085 "suphi1", "SupeRes hires [clear] (packed)", -1, 0x23, DM_FMT_RD,
3086 fmtProbeSupeRes,
3087 fmtDecodeSupeRes, NULL,
3088 { }, &dmC64CommonFormats[10]
3089 },
3090
3091 {
3092 "suphi2", "SupeRes hires [no-clear] (packed)", -1, 0x25, DM_FMT_RD,
3093 fmtProbeSupeRes,
3094 fmtDecodeSupeRes, NULL,
3095 { }, &dmC64CommonFormats[10]
3096 },
3097
3098 {
3099 "supmc1", "SupeRes multicolor [clear] (packed)", -1, 0x24, DM_FMT_RD,
3100 fmtProbeSupeRes,
3101 fmtDecodeSupeRes, NULL,
3102 { }, &dmC64CommonFormats[0]
3103 },
3104
3105 {
3106 "supmc2", "SupeRes multicolor [no-clear] (packed)", -1, 0x26, DM_FMT_RD,
3107 fmtProbeSupeRes,
3108 fmtDecodeSupeRes, NULL,
3109 { }, &dmC64CommonFormats[0]
3110 },
2877 }; 3111 };
2878 3112
2879 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]); 3113 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]);
2880 3114