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