Mercurial > hg > dmlib
comparison tools/libgfx.c @ 2064:3617ef01c1de
Separate ILBM and PBM subformats of IFF images.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 05 Dec 2018 13:31:59 +0200 |
parents | bd109c0a7b88 |
children | 451980580189 |
comparison
equal
deleted
inserted
replaced
2063:bd109c0a7b88 | 2064:3617ef01c1de |
---|---|
1499 DMIFFBMHD bmhd; | 1499 DMIFFBMHD bmhd; |
1500 Uint32 camg; | 1500 Uint32 camg; |
1501 int ncolors; | 1501 int ncolors; |
1502 DMColor *pal; | 1502 DMColor *pal; |
1503 Uint32 idsig; | 1503 Uint32 idsig; |
1504 char *idstr; | |
1504 } DMIFF; | 1505 } DMIFF; |
1505 | 1506 |
1506 | 1507 |
1507 static int fmtProbeIFF(const Uint8 *buf, const size_t len) | 1508 static int fmtProbeIFF(const Uint8 *buf, const size_t len) |
1508 { | 1509 { |
1800 return dmError(DMERR_INVALID_DATA, | 1801 return dmError(DMERR_INVALID_DATA, |
1801 "IFF: Not a IFF ILBM/PBM/ACBM file.\n"); | 1802 "IFF: Not a IFF ILBM/PBM/ACBM file.\n"); |
1802 } | 1803 } |
1803 | 1804 |
1804 dmMsg(3, "IFF: FORM is %s format image, with size %d bytes.\n", | 1805 dmMsg(3, "IFF: FORM is %s format image, with size %d bytes.\n", |
1805 iff.idsig == IFF_ID_ILBM ? "ILBM" : (iff.idsig == IFF_ID_PBM ? "PBM" : "ACBM"), | 1806 iff.idsig == IFF_ID_ILBM ? "ILBM" : |
1807 (iff.idsig == IFF_ID_PBM ? "PBM" : "ACBM"), | |
1806 chunk.size); | 1808 chunk.size); |
1807 | 1809 |
1808 while (!parsed && !dmfeof(fp)) | 1810 while (!parsed && !dmfeof(fp)) |
1809 { | 1811 { |
1810 // Read chunk header | 1812 // Read chunk header |
2189 else | 2191 else |
2190 return dmf_write_str(fp, buf, bufLen); | 2192 return dmf_write_str(fp, buf, bufLen); |
2191 } | 2193 } |
2192 | 2194 |
2193 | 2195 |
2194 int dmWriteIFFImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *cpspec) | 2196 int dmWriteIFFImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec) |
2195 { | 2197 { |
2196 DMIFF iff; | 2198 DMIFF iff; |
2197 Uint8 *buf = NULL; | 2199 Uint8 *buf = NULL; |
2198 size_t bufLen; | 2200 size_t bufLen; |
2199 int res = DMERR_OK; | 2201 int res = DMERR_OK; |
2200 DMImageConvSpec pspec, *spec = &pspec; | 2202 //DMImageConvSpec pspec, *spec = &pspec; |
2201 | 2203 |
2202 memcpy(&pspec, cpspec, sizeof(DMImageConvSpec)); | 2204 //memcpy(&pspec, cpspec, sizeof(DMImageConvSpec)); |
2203 | 2205 |
2204 // XXX: Non-paletted ILBM not supported! | 2206 // XXX: Non-paletted IFF not supported! |
2205 if (!spec->paletted) | 2207 if (!spec->paletted) |
2206 { | 2208 { |
2207 return dmError(DMERR_NOT_SUPPORTED, | 2209 return dmError(DMERR_NOT_SUPPORTED, |
2208 "Non-paletted IFF is not supported.\n"); | 2210 "Non-paletted IFF is not supported.\n"); |
2209 } | 2211 } |
2210 | 2212 |
2211 if (!spec->planar && spec->nplanes < 8) | 2213 switch (spec->format) |
2212 spec->nplanes = 8; | 2214 { |
2215 case DM_IMGFMT_IFF_ILBM: iff.idsig = IFF_ID_ILBM; iff.idstr = "ILBM"; break; | |
2216 case DM_IMGFMT_IFF_PBM : iff.idsig = IFF_ID_PBM; iff.idstr = "PBM"; break; | |
2217 case DM_IMGFMT_IFF_ACBM: iff.idsig = IFF_ID_ACBM; iff.idstr = "ACBM"; break; | |
2218 } | |
2213 | 2219 |
2214 // Setup headers | 2220 // Setup headers |
2215 iff.bmhd.x = 0; | 2221 iff.bmhd.x = 0; |
2216 iff.bmhd.y = 0; | 2222 iff.bmhd.y = 0; |
2217 iff.bmhd.w = img->width * spec->scaleX; | 2223 iff.bmhd.w = img->width * spec->scaleX; |
2224 | 2230 |
2225 iff.camg = 0; // XXX TODO: when/if HAM support | 2231 iff.camg = 0; // XXX TODO: when/if HAM support |
2226 iff.bmhd.masking = (img->ctransp < 0) ? IFF_MASK_NONE : spec->mask; | 2232 iff.bmhd.masking = (img->ctransp < 0) ? IFF_MASK_NONE : spec->mask; |
2227 iff.bmhd.compression = spec->compression ? IFF_COMP_BYTERUN1 : IFF_COMP_NONE; | 2233 iff.bmhd.compression = spec->compression ? IFF_COMP_BYTERUN1 : IFF_COMP_NONE; |
2228 iff.bmhd.transp = (img->ctransp >= 0 && spec->mask == IFF_MASK_TRANSP) ? img->ctransp : 0xffff; | 2234 iff.bmhd.transp = (img->ctransp >= 0 && spec->mask == IFF_MASK_TRANSP) ? img->ctransp : 0xffff; |
2229 iff.bmhd.nplanes = spec->nplanes; | 2235 iff.bmhd.nplanes = (iff.idsig == IFF_ID_PBM && spec->nplanes < 8) ? 8 : spec->nplanes; |
2230 iff.idsig = spec->planar ? IFF_ID_ILBM : IFF_ID_PBM; | |
2231 | 2236 |
2232 dmMsg(2, "IFF: nplanes=%d, comp=%d, mask=%d\n", | 2237 dmMsg(2, "IFF: nplanes=%d, comp=%d, mask=%d\n", |
2233 iff.bmhd.nplanes, iff.bmhd.compression, iff.bmhd.masking); | 2238 iff.bmhd.nplanes, iff.bmhd.compression, iff.bmhd.masking); |
2234 | 2239 |
2235 // Write IFF FORM header | 2240 // Write IFF FORM header |
2239 // Write IFF ILBM/PBM signature | 2244 // Write IFF ILBM/PBM signature |
2240 if (!dmf_write_be32(fp, iff.idsig)) | 2245 if (!dmf_write_be32(fp, iff.idsig)) |
2241 { | 2246 { |
2242 res = dmError(DMERR_FWRITE, | 2247 res = dmError(DMERR_FWRITE, |
2243 "IFF: Error writing %s signature.\n", | 2248 "IFF: Error writing %s signature.\n", |
2244 spec->planar ? "ILBM" : "PBM"); | 2249 iff.idstr); |
2245 goto out; | 2250 goto out; |
2246 } | 2251 } |
2247 | 2252 |
2248 // Write BMHD chunk and data | 2253 // Write BMHD chunk and data |
2249 if ((res = dmWriteIFFChunkHdr(fp, &iff.chBMHD, IFF_ID_BMHD)) != DMERR_OK || | 2254 if ((res = dmWriteIFFChunkHdr(fp, &iff.chBMHD, IFF_ID_BMHD)) != DMERR_OK || |
2317 // Encode the body | 2322 // Encode the body |
2318 // | 2323 // |
2319 if ((res = dmWriteIFFChunkHdr(fp, &iff.chBODY, IFF_ID_BODY)) != DMERR_OK) | 2324 if ((res = dmWriteIFFChunkHdr(fp, &iff.chBODY, IFF_ID_BODY)) != DMERR_OK) |
2320 goto out; | 2325 goto out; |
2321 | 2326 |
2322 | |
2323 // Allocate encoding buffer | 2327 // Allocate encoding buffer |
2324 if (spec->planar) | 2328 if (iff.idsig == IFF_ID_ILBM) |
2325 bufLen = (((img->width * spec->scaleX) + 15) / 16) * 2; | 2329 bufLen = (((img->width * spec->scaleX) + 15) / 16) * 2; |
2326 else | 2330 else |
2327 bufLen = img->width * spec->scaleX; | 2331 bufLen = img->width * spec->scaleX; |
2328 | 2332 |
2329 dmMsg(2, "IFF: Line/plane row size %d bytes.\n", bufLen); | 2333 dmMsg(2, "IFF: Line/plane row size %d bytes.\n", bufLen); |
2330 | 2334 |
2331 if ((buf = dmMalloc(bufLen)) == NULL) | 2335 if ((buf = dmMalloc(bufLen)) == NULL) |
2332 return DMERR_MALLOC; | 2336 return DMERR_MALLOC; |
2333 | 2337 |
2334 // Encode the body | 2338 // Encode the body |
2335 for (int yc = 0; yc < img->height; yc++) | 2339 { |
2336 for (int yscale = 0; yscale < spec->scaleY; yscale++) | 2340 for (int yc = 0; yc < img->height; yc++) |
2337 { | 2341 for (int yscale = 0; yscale < spec->scaleY; yscale++) |
2338 const Uint8 *sp = img->data + (yc * img->pitch); | 2342 { |
2339 | 2343 const Uint8 *sp = img->data + (yc * img->pitch); |
2340 if (spec->planar) | 2344 |
2341 { | 2345 if (iff.idsig == IFF_ID_ILBM) |
2342 for (int plane = 0; plane < spec->nplanes; plane++) | 2346 { |
2343 { | 2347 for (int plane = 0; plane < spec->nplanes; plane++) |
2344 // Encode bitplane | 2348 { |
2345 dmMemset(buf, 0, bufLen); | 2349 // Encode bitplane |
2346 | 2350 dmMemset(buf, 0, bufLen); |
2351 | |
2352 for (int xc = 0; xc < img->width * spec->scaleX; xc++) | |
2353 buf[xc / 8] |= ((sp[xc / spec->scaleX] >> plane) & 1) << (7 - (xc & 7)); | |
2354 | |
2355 // Compress / write data | |
2356 if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen)) | |
2357 { | |
2358 res = dmError(DMERR_FWRITE, | |
2359 "IFF: Error writing ILBM image plane #%d @ row %d.\n", | |
2360 plane, yc); | |
2361 goto out; | |
2362 } | |
2363 } | |
2364 | |
2365 // Write mask data, if any | |
2366 if (iff.bmhd.masking == IFF_MASK_HAS_MASK) | |
2367 { | |
2368 dmMemset(buf, 0, bufLen); | |
2369 | |
2370 for (int xc = 0; xc < img->width * spec->scaleX; xc++) | |
2371 buf[xc / 8] |= (sp[xc / spec->scaleX] == img->ctransp) << (7 - (xc & 7)); | |
2372 | |
2373 if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen)) | |
2374 { | |
2375 res = dmError(DMERR_FWRITE, | |
2376 "IFF: Error writing ILBM mask plane %d.\n", yc); | |
2377 goto out; | |
2378 } | |
2379 } | |
2380 } | |
2381 else | |
2382 { | |
2347 for (int xc = 0; xc < img->width * spec->scaleX; xc++) | 2383 for (int xc = 0; xc < img->width * spec->scaleX; xc++) |
2348 buf[xc / 8] |= ((sp[xc / spec->scaleX] >> plane) & 1) << (7 - (xc & 7)); | 2384 buf[xc] = sp[xc / spec->scaleX]; |
2349 | 2385 |
2350 // Compress / write data | |
2351 if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen)) | 2386 if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen)) |
2352 { | 2387 { |
2353 res = dmError(DMERR_FWRITE, | 2388 res = dmError(DMERR_FWRITE, |
2354 "IFF: Error writing image plane #%d @ %d.\n", | 2389 "IFF: Error writing PBM image row #%d.\n", yc); |
2355 plane, yc); | |
2356 goto out; | 2390 goto out; |
2357 } | 2391 } |
2358 } | |
2359 | |
2360 // Write mask data, if any | |
2361 if (iff.bmhd.masking == IFF_MASK_HAS_MASK) | |
2362 { | |
2363 dmMemset(buf, 0, bufLen); | |
2364 | |
2365 for (int xc = 0; xc < img->width * spec->scaleX; xc++) | |
2366 buf[xc / 8] |= (sp[xc / spec->scaleX] == img->ctransp) << (7 - (xc & 7)); | |
2367 | |
2368 if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen)) | |
2369 { | |
2370 res = dmError(DMERR_FWRITE, | |
2371 "IFF: Error writing mask plane %d.\n", yc); | |
2372 goto out; | |
2373 } | |
2374 } | |
2375 } | |
2376 else | |
2377 { | |
2378 for (int xc = 0; xc < img->width * spec->scaleX; xc++) | |
2379 buf[xc] = sp[xc / spec->scaleX]; | |
2380 | |
2381 if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen)) | |
2382 { | |
2383 res = dmError(DMERR_FWRITE, | |
2384 "IFF: Error writing PBM image row #%d.\n", yc); | |
2385 goto out; | |
2386 } | 2392 } |
2387 } | 2393 } |
2388 } | 2394 } |
2389 | 2395 |
2390 if ((res = dmWriteIFFChunkFinish(fp, &iff.chBODY)) != DMERR_OK) | 2396 if ((res = dmWriteIFFChunkFinish(fp, &iff.chBODY)) != DMERR_OK) |
2421 "pcx", "Z-Soft Paintbrush", | 2427 "pcx", "Z-Soft Paintbrush", |
2422 DM_IMGFMT_PCX, DM_FMT_RDWR, | 2428 DM_IMGFMT_PCX, DM_FMT_RDWR, |
2423 fmtProbePCX, dmReadPCXImage, dmWritePCXImage, | 2429 fmtProbePCX, dmReadPCXImage, dmWritePCXImage, |
2424 }, | 2430 }, |
2425 { | 2431 { |
2426 "iff", "IFF ILBM/PBM/ACBM", | 2432 "lbm", "IFF ILBM (interleaved/old DP)", |
2427 DM_IMGFMT_IFF, DM_FMT_RDWR, | 2433 DM_IMGFMT_IFF_ILBM, DM_FMT_RDWR, |
2434 fmtProbeIFF, dmReadIFFImage, dmWriteIFFImage, | |
2435 }, | |
2436 { | |
2437 "pbm", "IFF PBM (DP2e)", | |
2438 DM_IMGFMT_IFF_PBM, DM_FMT_RDWR, | |
2439 fmtProbeIFF, dmReadIFFImage, dmWriteIFFImage, | |
2428 fmtProbeIFF, dmReadIFFImage, dmWriteIFFImage, | 2440 fmtProbeIFF, dmReadIFFImage, dmWriteIFFImage, |
2429 }, | 2441 }, |
2430 { | 2442 { |
2431 "raw", "Plain bitplaned (planar or non-planar) RAW", | 2443 "raw", "Plain bitplaned (planar or non-planar) RAW", |
2432 DM_IMGFMT_RAW, DM_FMT_WR, | 2444 DM_IMGFMT_RAW, DM_FMT_WR, |