comparison tools/libgfx.c @ 1609:c29adf5ce240

Convert libgfx file format routines to use DMResource instead of stdio FILE. Also do necessary changes in gfxconv due to these API changes.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 14 May 2018 12:42:24 +0300
parents fd0d1b4efc83
children 70b04c16aa40
comparison
equal deleted inserted replaced
1608:7f9fe2a9a87e 1609:c29adf5ce240
4 * (C) Copyright 2012-2017 Tecnic Software productions (TNSP) 4 * (C) Copyright 2012-2017 Tecnic Software productions (TNSP)
5 * 5 *
6 * Please read file 'COPYING' for information on license and distribution. 6 * Please read file 'COPYING' for information on license and distribution.
7 */ 7 */
8 #include "libgfx.h" 8 #include "libgfx.h"
9 #include "dmfile.h" 9 #include "dmresw.h"
10 10
11 #ifdef DM_USE_LIBPNG 11 #ifdef DM_USE_LIBPNG
12 #include <png.h> 12 #include <png.h>
13 #endif 13 #endif
14 14
64 } 64 }
65 65
66 66
67 static BOOL dmPutByteFILE(DMBitStreamContext *ctx, const Uint8 val) 67 static BOOL dmPutByteFILE(DMBitStreamContext *ctx, const Uint8 val)
68 { 68 {
69 return fputc(val, (FILE *) ctx->handle) == val; 69 return dmf_write_byte((DMResource *) ctx->handle, val);
70 } 70 }
71 71
72 72
73 int dmInitBitStreamFILE(DMBitStreamContext *ctx, FILE *fp) 73 int dmInitBitStreamFILE(DMBitStreamContext *ctx, DMResource *fp)
74 { 74 {
75 if (ctx == NULL || fp == NULL) 75 if (ctx == NULL || fp == NULL)
76 return DMERR_NULLPTR; 76 return DMERR_NULLPTR;
77 77
78 ctx->putByte = dmPutByteFILE; 78 ctx->putByte = dmPutByteFILE;
145 } 145 }
146 146
147 147
148 BOOL dmPaletteAlloc(DMColor **ppal, int ncolors, int ctransp) 148 BOOL dmPaletteAlloc(DMColor **ppal, int ncolors, int ctransp)
149 { 149 {
150 int i;
151
152 if (ppal == NULL) 150 if (ppal == NULL)
153 return FALSE; 151 return FALSE;
154 152
155 // Allocate desired amount of palette 153 // Allocate desired amount of palette
156 if ((*ppal = dmCalloc(ncolors, sizeof(DMColor))) == NULL) 154 if ((*ppal = dmCalloc(ncolors, sizeof(DMColor))) == NULL)
157 return FALSE; 155 return FALSE;
158 156
159 // Set alpha values to max, except for transparent color 157 // Set alpha values to max, except for transparent color
160 for (i = 0; i < ncolors; i++) 158 for (int i = 0; i < ncolors; i++)
161 { 159 {
162 (*ppal)[i].a = (i == ctransp) ? 0 : 255; 160 (*ppal)[i].a = (i == ctransp) ? 0 : 255;
163 } 161 }
164 162
165 return TRUE; 163 return TRUE;
175 img->ctransp = ctransp; 173 img->ctransp = ctransp;
176 return dmPaletteAlloc(&(img->pal), ncolors, ctransp); 174 return dmPaletteAlloc(&(img->pal), ncolors, ctransp);
177 } 175 }
178 176
179 177
180 static BOOL dmReadPaletteData(FILE *fp, DMColor *pal, int ncolors) 178 static BOOL dmReadPaletteData(DMResource *fp, DMColor *pal, int ncolors)
181 { 179 {
182 int i; 180 for (int i = 0; i < ncolors; i++)
183
184 for (i = 0; i < ncolors; i++)
185 { 181 {
186 Uint8 colR, colG, colB; 182 Uint8 colR, colG, colB;
187 if (!dm_fread_byte(fp, &colR) || 183 if (!dmf_read_byte(fp, &colR) ||
188 !dm_fread_byte(fp, &colG) || 184 !dmf_read_byte(fp, &colG) ||
189 !dm_fread_byte(fp, &colB)) 185 !dmf_read_byte(fp, &colB))
190 return FALSE; 186 return FALSE;
191 187
192 pal[i].r = colR; 188 pal[i].r = colR;
193 pal[i].g = colG; 189 pal[i].g = colG;
194 pal[i].b = colB; 190 pal[i].b = colB;
299 dmFree(row); 295 dmFree(row);
300 return res; 296 return res;
301 } 297 }
302 298
303 299
304 #define DMCOL(x) (((x) >> 4) & 0xf) 300 int dmWriteRAWImageFILE(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec)
305
306 int dmWriteIFFMasterRAWPalette(FILE *fp,
307 const DMImage *img, int ncolors,
308 const char *indent, const char *type)
309 {
310 int i;
311
312 for (i = 0; i < ncolors; i++)
313 {
314 int color;
315 if (i < img->ncolors)
316 {
317 color = (DMCOL(img->pal[i].r) << 8) |
318 (DMCOL(img->pal[i].g) << 4) |
319 (DMCOL(img->pal[i].b));
320 }
321 else
322 color = 0;
323
324 fprintf(fp, "%s%s $%04X\n",
325 indent != NULL ? indent : "\t",
326 type != NULL ? type : "dc.w",
327 color);
328 }
329
330 return DMERR_OK;
331 }
332
333
334 int dmWriteRAWImageFILE(FILE *fp, const DMImage *img, const DMImageConvSpec *spec)
335 { 301 {
336 int xc, yc, plane, res; 302 int xc, yc, plane, res;
337 DMBitStreamContext bs; 303 DMBitStreamContext bs;
338 304
339 if ((res = dmInitBitStreamFILE(&bs, fp)) != DMERR_OK) 305 if ((res = dmInitBitStreamFILE(&bs, fp)) != DMERR_OK)
373 } 339 }
374 340
375 341
376 int dmWriteRAWImage(const char *filename, const DMImage *img, const DMImageConvSpec *spec) 342 int dmWriteRAWImage(const char *filename, const DMImage *img, const DMImageConvSpec *spec)
377 { 343 {
378 FILE *fp; 344 DMResource *fp;
379 int res; 345 int res;
380 346
381 if ((fp = fopen(filename, "wb")) == NULL) 347 if ((res = dmf_open_stdio(filename, "wb", &fp)) != DMERR_OK)
382 { 348 {
383 return dmError(DMERR_FOPEN, 349 return dmError(DMERR_FOPEN,
384 "RAW: Could not open file '%s' for writing.\n", 350 "RAW: Could not open file '%s' for writing.\n",
385 filename); 351 filename);
386 } 352 }
387 353
388 res = dmWriteRAWImageFILE(fp, img, spec); 354 res = dmWriteRAWImageFILE(fp, img, spec);
389 355
390 fclose(fp); 356 dmf_close(fp);
391 return res; 357 return res;
392 } 358 }
393 359
394 360
395 static int dmWritePPMRow(void *cbdata, const Uint8 *row, const size_t len) 361 static int dmWritePPMRow(void *cbdata, const Uint8 *row, const size_t len)
396 { 362 {
397 if (fwrite(row, sizeof(Uint8), len, (FILE *) cbdata) == len) 363 if (dmf_write_str((DMResource *) cbdata, row, len))
398 return DMERR_OK; 364 return DMERR_OK;
399 else 365 else
400 return DMERR_FWRITE; 366 return DMERR_FWRITE;
401 } 367 }
402 368
403 369
404 int dmWritePPMImageFILE(FILE *fp, const DMImage *img, const DMImageConvSpec *spec) 370 int dmWritePPMImageFILE(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec)
405 { 371 {
406 DMImageConvSpec tmpSpec; 372 DMImageConvSpec tmpSpec;
407 373
408 // Write PPM header 374 // Write PPM header
409 fprintf(fp, 375 char *tmp = dm_strdup_printf(
410 "P6\n%d %d\n255\n", 376 "P6\n%d %d\n255\n",
411 img->width * spec->scaleX, 377 img->width * spec->scaleX,
412 img->height * spec->scaleY); 378 img->height * spec->scaleY);
379
380 if (tmp == NULL)
381 return DMERR_MALLOC;
382
383 dmfputs(tmp, fp);
384 dmFree(tmp);
413 385
414 // Write image data 386 // Write image data
415 memcpy(&tmpSpec, spec, sizeof(DMImageConvSpec)); 387 memcpy(&tmpSpec, spec, sizeof(DMImageConvSpec));
416 tmpSpec.format = DM_IFMT_RGB; 388 tmpSpec.format = DM_IFMT_RGB;
417 return dmWriteImageData(img, (void *) fp, dmWritePPMRow, &tmpSpec); 389 return dmWriteImageData(img, (void *) fp, dmWritePPMRow, &tmpSpec);
418 } 390 }
419 391
420 392
421 int dmWritePPMImage(const char *filename, const DMImage *img, const DMImageConvSpec *spec) 393 int dmWritePPMImage(const char *filename, const DMImage *img, const DMImageConvSpec *spec)
422 { 394 {
423 FILE *fp; 395 DMResource *fp;
424 int res; 396 int res;
425 397
426 // Create output file 398 // Create output file
427 if ((fp = fopen(filename, "wb")) == NULL) 399 if ((res = dmf_open_stdio(filename, "wb", &fp)) != DMERR_OK)
428 { 400 {
429 return dmError(DMERR_FOPEN, 401 return dmError(DMERR_FOPEN,
430 "PPM: could not open file '%s' for writing.\n", 402 "PPM: could not open file '%s' for writing.\n",
431 filename); 403 filename);
432 } 404 }
433 405
434 res = dmWritePPMImageFILE(fp, img, spec); 406 res = dmWritePPMImageFILE(fp, img, spec);
435 407
436 fclose(fp); 408 dmf_close(fp);
437 return res; 409 return res;
438 } 410 }
439 411
440 412
441 #ifdef DM_USE_LIBPNG 413 #ifdef DM_USE_LIBPNG
451 423
452 return DMERR_OK; 424 return DMERR_OK;
453 } 425 }
454 426
455 427
456 int dmWritePNGImageFILE(FILE *fp, const DMImage *img, const DMImageConvSpec *spec) 428 static void dmPNGWriteData(png_structp png_ptr, png_bytep data, png_size_t length)
429 {
430 DMResource *res = (DMResource *) png_get_io_ptr(png_ptr);
431
432 // XXX TODO: How the fuck does one do error handling here?
433 dmf_write_str(res, data, length);
434 }
435
436
437 static void dmPNGWriteFlush(png_structp png_ptr)
438 {
439 (void) png_ptr;
440 }
441
442
443 int dmWritePNGImageFILE(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec)
457 { 444 {
458 png_structp png_ptr = NULL; 445 png_structp png_ptr = NULL;
459 png_infop info_ptr = NULL; 446 png_infop info_ptr = NULL;
460 int fmt, res; 447 int fmt, res;
461 448
486 "PNG: Error during image writing..\n"); 473 "PNG: Error during image writing..\n");
487 goto error; 474 goto error;
488 } 475 }
489 476
490 res = DMERR_OK; 477 res = DMERR_OK;
491 png_init_io(png_ptr, fp); 478 png_set_write_fn(png_ptr, fp, dmPNGWriteData, dmPNGWriteFlush);
492 479
493 // Write PNG header info 480 // Write PNG header info
494 switch (spec->format) 481 switch (spec->format)
495 { 482 {
496 case DM_IFMT_PALETTE: fmt = PNG_COLOR_TYPE_PALETTE; break; 483 case DM_IFMT_PALETTE: fmt = PNG_COLOR_TYPE_PALETTE; break;
562 549
563 550
564 int dmWritePNGImage(const char *filename, const DMImage *img, const DMImageConvSpec *spec) 551 int dmWritePNGImage(const char *filename, const DMImage *img, const DMImageConvSpec *spec)
565 { 552 {
566 int res; 553 int res;
567 FILE *fp; 554 DMResource *fp;
568 555
569 if ((fp = fopen(filename, "wb")) == NULL) 556 if ((res = dmf_open_stdio(filename, "wb", &fp)) != DMERR_OK)
570 { 557 {
571 return dmError(DMERR_FOPEN, 558 return dmError(DMERR_FOPEN,
572 "PNG: could not open file '%s' for writing.\n", 559 "PNG: could not open file '%s' for writing.\n",
573 filename); 560 filename);
574 } 561 }
575 562
576 res = dmWritePNGImageFILE(fp, img, spec); 563 res = dmWritePNGImageFILE(fp, img, spec);
577 564
578 fclose(fp); 565 dmf_close(fp);
579 return res; 566 return res;
580 } 567 }
581 568
582 569
583 int dmReadPNGImageFILE(FILE *fp, DMImage **pimg) 570 void dmPNGReadData(png_structp png_ptr, png_bytep data, png_size_t length)
571 {
572 DMResource *res = (DMResource *) png_get_io_ptr(png_ptr);
573
574 // XXX TODO: How the fuck does one do error handling here?
575 dmf_read_str(res, data, length);
576 }
577
578 int dmReadPNGImageFILE(DMResource *fp, DMImage **pimg)
584 { 579 {
585 png_structp png_ptr = NULL; 580 png_structp png_ptr = NULL;
586 png_infop info_ptr = NULL; 581 png_infop info_ptr = NULL;
587 png_colorp palette = NULL; 582 png_colorp palette = NULL;
588 png_bytep *row_pointers = NULL; 583 png_bytep *row_pointers = NULL;
618 res = dmError(DMERR_INIT_FAIL, 613 res = dmError(DMERR_INIT_FAIL,
619 "PNG: Error during image reading.\n"); 614 "PNG: Error during image reading.\n");
620 goto error; 615 goto error;
621 } 616 }
622 617
623 png_init_io(png_ptr, fp); 618 png_set_read_fn(png_ptr, fp, dmPNGReadData);
624 619
625 // Read image information 620 // Read image information
626 png_read_info(png_ptr, info_ptr); 621 png_read_info(png_ptr, info_ptr);
627 622
628 png_get_IHDR(png_ptr, info_ptr, &width, &height, 623 png_get_IHDR(png_ptr, info_ptr, &width, &height,
750 745
751 746
752 int dmReadPNGImage(const char *filename, DMImage **img) 747 int dmReadPNGImage(const char *filename, DMImage **img)
753 { 748 {
754 int res; 749 int res;
755 FILE *fp; 750 DMResource *fp;
756 751
757 if ((fp = fopen(filename, "rb")) == NULL) 752 if ((res = dmf_open_stdio(filename, "rb", &fp)) != DMERR_OK)
758 { 753 {
759 return dmError(DMERR_FOPEN, 754 return dmError(DMERR_FOPEN,
760 "PNG: Could not open file '%s' for reading.\n", 755 "PNG: Could not open file '%s' for reading.\n",
761 filename); 756 filename);
762 } 757 }
763 758
764 res = dmReadPNGImageFILE(fp, img); 759 res = dmReadPNGImageFILE(fp, img);
765 760
766 fclose(fp); 761 dmf_close(fp);
767 return res; 762 return res;
768 } 763 }
769 #endif 764 #endif
770 765
771 766
804 typedef struct 799 typedef struct
805 { 800 {
806 DMPCXHeader *header; 801 DMPCXHeader *header;
807 Uint8 *buf; 802 Uint8 *buf;
808 size_t bufLen, bufOffs; 803 size_t bufLen, bufOffs;
809 FILE *fp; 804 DMResource *fp;
810 } DMPCXData; 805 } DMPCXData;
811 806
812 807
813 // Returns one byte from row buffer (of length len) at offset soffs, 808 // Returns one byte from row buffer (of length len) at offset soffs,
814 // OR zero if the offset is outside buffer. 809 // OR zero if the offset is outside buffer.
819 814
820 static BOOL dmPCXFlush(DMPCXData *pcx) 815 static BOOL dmPCXFlush(DMPCXData *pcx)
821 { 816 {
822 BOOL ret = TRUE; 817 BOOL ret = TRUE;
823 if (pcx->bufOffs > 0) 818 if (pcx->bufOffs > 0)
824 ret = fwrite(pcx->buf, sizeof(Uint8), pcx->bufOffs, pcx->fp) == pcx->bufOffs; 819 ret = dmf_write_str(pcx->fp, pcx->buf, pcx->bufOffs);
825 820
826 pcx->bufOffs = 0; 821 pcx->bufOffs = 0;
827 return ret; 822 return ret;
828 } 823 }
829 824
897 892
898 return DMERR_OK; 893 return DMERR_OK;
899 } 894 }
900 895
901 896
902 int dmWritePCXImageFILE(FILE *fp, const DMImage *img, const DMImageConvSpec *pspec) 897 int dmWritePCXImageFILE(DMResource *fp, const DMImage *img, const DMImageConvSpec *pspec)
903 { 898 {
904 DMPCXData pcx; 899 DMPCXData pcx;
905 DMPCXHeader hdr; 900 DMPCXHeader hdr;
906 DMImageConvSpec spec; 901 DMImageConvSpec spec;
907 int res; 902 int res;
972 pcx.bufLen); 967 pcx.bufLen);
973 goto error; 968 goto error;
974 } 969 }
975 970
976 // Write PCX header 971 // Write PCX header
977 if (!dm_fwrite_byte(pcx.fp, hdr.manufacturer) || 972 if (!dmf_write_byte(pcx.fp, hdr.manufacturer) ||
978 !dm_fwrite_byte(pcx.fp, hdr.version) || 973 !dmf_write_byte(pcx.fp, hdr.version) ||
979 !dm_fwrite_byte(pcx.fp, hdr.encoding) || 974 !dmf_write_byte(pcx.fp, hdr.encoding) ||
980 !dm_fwrite_byte(pcx.fp, hdr.bitsPerPlane)) 975 !dmf_write_byte(pcx.fp, hdr.bitsPerPlane))
981 { 976 {
982 res = dmError(DMERR_FWRITE, 977 res = dmError(DMERR_FWRITE,
983 "PCX: Could not write basic header data.\n"); 978 "PCX: Could not write basic header data.\n");
984 goto error; 979 goto error;
985 } 980 }
986 981
987 if (!dm_fwrite_le16(pcx.fp, hdr.xmin) || 982 if (!dmf_write_le16(pcx.fp, hdr.xmin) ||
988 !dm_fwrite_le16(pcx.fp, hdr.ymin) || 983 !dmf_write_le16(pcx.fp, hdr.ymin) ||
989 !dm_fwrite_le16(pcx.fp, hdr.xmax) || 984 !dmf_write_le16(pcx.fp, hdr.xmax) ||
990 !dm_fwrite_le16(pcx.fp, hdr.ymax) || 985 !dmf_write_le16(pcx.fp, hdr.ymax) ||
991 !dm_fwrite_le16(pcx.fp, hdr.hres) || 986 !dmf_write_le16(pcx.fp, hdr.hres) ||
992 !dm_fwrite_le16(pcx.fp, hdr.vres)) 987 !dmf_write_le16(pcx.fp, hdr.vres))
993 { 988 {
994 res = dmError(DMERR_FWRITE, 989 res = dmError(DMERR_FWRITE,
995 "PCX: Could not write image dimensions.\n"); 990 "PCX: Could not write image dimensions.\n");
996 goto error; 991 goto error;
997 } 992 }
998 993
999 if (!dm_fwrite_str(pcx.fp, (Uint8 *) &hdr.colorMap, sizeof(hdr.colorMap))) 994 if (!dmf_write_str(pcx.fp, (Uint8 *) &hdr.colorMap, sizeof(hdr.colorMap)))
1000 { 995 {
1001 res = dmError(DMERR_FWRITE, 996 res = dmError(DMERR_FWRITE,
1002 "PCX: Could not write colormap.\n"); 997 "PCX: Could not write colormap.\n");
1003 goto error; 998 goto error;
1004 } 999 }
1005 1000
1006 if (!dm_fwrite_byte(pcx.fp, hdr.reserved) || 1001 if (!dmf_write_byte(pcx.fp, hdr.reserved) ||
1007 !dm_fwrite_byte(pcx.fp, hdr.nplanes) || 1002 !dmf_write_byte(pcx.fp, hdr.nplanes) ||
1008 !dm_fwrite_le16(pcx.fp, hdr.bpl) || 1003 !dmf_write_le16(pcx.fp, hdr.bpl) ||
1009 !dm_fwrite_le16(pcx.fp, hdr.palInfo) || 1004 !dmf_write_le16(pcx.fp, hdr.palInfo) ||
1010 !dm_fwrite_le16(pcx.fp, hdr.hScreenSize) || 1005 !dmf_write_le16(pcx.fp, hdr.hScreenSize) ||
1011 !dm_fwrite_le16(pcx.fp, hdr.vScreenSize) || 1006 !dmf_write_le16(pcx.fp, hdr.vScreenSize) ||
1012 !dm_fwrite_str(pcx.fp, (Uint8 *) &hdr.filler, sizeof(hdr.filler))) 1007 !dmf_write_str(pcx.fp, (Uint8 *) &hdr.filler, sizeof(hdr.filler)))
1013 { 1008 {
1014 res = dmError(DMERR_FWRITE, 1009 res = dmError(DMERR_FWRITE,
1015 "PCX: Could not write header remainder.\n"); 1010 "PCX: Could not write header remainder.\n");
1016 goto error; 1011 goto error;
1017 } 1012 }
1023 if (spec.paletted) 1018 if (spec.paletted)
1024 { 1019 {
1025 int i; 1020 int i;
1026 dmMsg(2, "PCX: Writing palette of %d active entries.\n", img->ncolors); 1021 dmMsg(2, "PCX: Writing palette of %d active entries.\n", img->ncolors);
1027 1022
1028 dm_fwrite_byte(pcx.fp, 0x0C); 1023 dmf_write_byte(pcx.fp, 0x0C);
1029 1024
1030 for (i = 0; i < img->ncolors; i++) 1025 for (i = 0; i < img->ncolors; i++)
1031 { 1026 {
1032 if (!dm_fwrite_byte(pcx.fp, img->pal[i].r) || 1027 if (!dmf_write_byte(pcx.fp, img->pal[i].r) ||
1033 !dm_fwrite_byte(pcx.fp, img->pal[i].g) || 1028 !dmf_write_byte(pcx.fp, img->pal[i].g) ||
1034 !dm_fwrite_byte(pcx.fp, img->pal[i].b)) 1029 !dmf_write_byte(pcx.fp, img->pal[i].b))
1035 { 1030 {
1036 res = dmError(DMERR_FWRITE, 1031 res = dmError(DMERR_FWRITE,
1037 "PCX: Could not write palette data.\n"); 1032 "PCX: Could not write palette data.\n");
1038 goto error; 1033 goto error;
1039 } 1034 }
1040 } 1035 }
1041 1036
1042 // Pad the palette, if necessary 1037 // Pad the palette, if necessary
1043 for (; i < 256; i++) 1038 for (; i < 256; i++)
1044 { 1039 {
1045 if (!dm_fwrite_byte(pcx.fp, 0) || 1040 if (!dmf_write_byte(pcx.fp, 0) ||
1046 !dm_fwrite_byte(pcx.fp, 0) || 1041 !dmf_write_byte(pcx.fp, 0) ||
1047 !dm_fwrite_byte(pcx.fp, 0)) 1042 !dmf_write_byte(pcx.fp, 0))
1048 { 1043 {
1049 res = dmError(DMERR_FWRITE, 1044 res = dmError(DMERR_FWRITE,
1050 "PCX: Could not write palette data.\n"); 1045 "PCX: Could not write palette data.\n");
1051 goto error; 1046 goto error;
1052 } 1047 }
1059 } 1054 }
1060 1055
1061 1056
1062 int dmWritePCXImage(const char *filename, const DMImage *img, const DMImageConvSpec *spec) 1057 int dmWritePCXImage(const char *filename, const DMImage *img, const DMImageConvSpec *spec)
1063 { 1058 {
1064 FILE *fp; 1059 DMResource *fp;
1065 int res; 1060 int res;
1066 1061
1067 if ((fp = fopen(filename, "wb")) == NULL) 1062 if ((res = dmf_open_stdio(filename, "wb", &fp)) != DMERR_OK)
1068 { 1063 {
1069 return dmError(DMERR_FOPEN, 1064 return dmError(DMERR_FOPEN,
1070 "PCX: Could not open file '%s' for writing.\n", 1065 "PCX: Could not open file '%s' for writing.\n",
1071 filename); 1066 filename);
1072 } 1067 }
1073 1068
1074 res = dmWritePCXImageFILE(fp, img, spec); 1069 res = dmWritePCXImageFILE(fp, img, spec);
1075 1070
1076 fclose(fp); 1071 dmf_close(fp);
1077 return res; 1072 return res;
1078 } 1073 }
1079 1074
1080 1075
1081 static BOOL dmPCXDecodeRLERow(FILE *fp, Uint8 *buf, const size_t bufLen) 1076 static BOOL dmPCXDecodeRLERow(DMResource *fp, Uint8 *buf, const size_t bufLen)
1082 { 1077 {
1083 size_t offs = 0; 1078 size_t offs = 0;
1084 do 1079 do
1085 { 1080 {
1086 int count; 1081 int count;
1087 Uint8 data; 1082 Uint8 data;
1088 1083
1089 if (!dm_fread_byte(fp, &data)) 1084 if (!dmf_read_byte(fp, &data))
1090 return FALSE; 1085 return FALSE;
1091 1086
1092 if ((data & 0xC0) == 0xC0) 1087 if ((data & 0xC0) == 0xC0)
1093 { 1088 {
1094 BOOL skip = FALSE; 1089 BOOL skip = FALSE;
1113 // Error out on "invalid" data 1108 // Error out on "invalid" data
1114 return FALSE; 1109 return FALSE;
1115 } 1110 }
1116 } 1111 }
1117 1112
1118 if (!skip && !dm_fread_byte(fp, &data)) 1113 if (!skip && !dmf_read_byte(fp, &data))
1119 return FALSE; 1114 return FALSE;
1120 } 1115 }
1121 else 1116 else
1122 count = 1; 1117 count = 1;
1123 1118
1132 1127
1133 return TRUE; 1128 return TRUE;
1134 } 1129 }
1135 1130
1136 1131
1137 int dmReadPCXImageFILE(FILE *fp, DMImage **pimg) 1132 int dmReadPCXImageFILE(DMResource *fp, DMImage **pimg)
1138 { 1133 {
1139 DMImage *img; 1134 DMImage *img;
1140 DMPCXData pcx; 1135 DMPCXData pcx;
1141 DMPCXHeader hdr; 1136 DMPCXHeader hdr;
1142 int res = 0; 1137 int res = 0;
1143 BOOL isPaletted; 1138 BOOL isPaletted;
1144 pcx.buf = NULL; 1139 pcx.buf = NULL;
1145 1140
1146 // Read PCX header 1141 // Read PCX header
1147 if (!dm_fread_byte(fp, &hdr.manufacturer) || 1142 if (!dmf_read_byte(fp, &hdr.manufacturer) ||
1148 !dm_fread_byte(fp, &hdr.version) || 1143 !dmf_read_byte(fp, &hdr.version) ||
1149 !dm_fread_byte(fp, &hdr.encoding) || 1144 !dmf_read_byte(fp, &hdr.encoding) ||
1150 !dm_fread_byte(fp, &hdr.bitsPerPlane) || 1145 !dmf_read_byte(fp, &hdr.bitsPerPlane) ||
1151 !dm_fread_le16(fp, &hdr.xmin) || 1146 !dmf_read_le16(fp, &hdr.xmin) ||
1152 !dm_fread_le16(fp, &hdr.ymin) || 1147 !dmf_read_le16(fp, &hdr.ymin) ||
1153 !dm_fread_le16(fp, &hdr.xmax) || 1148 !dmf_read_le16(fp, &hdr.xmax) ||
1154 !dm_fread_le16(fp, &hdr.ymax) || 1149 !dmf_read_le16(fp, &hdr.ymax) ||
1155 !dm_fread_le16(fp, &hdr.hres) || 1150 !dmf_read_le16(fp, &hdr.hres) ||
1156 !dm_fread_le16(fp, &hdr.vres) || 1151 !dmf_read_le16(fp, &hdr.vres) ||
1157 !dm_fread_str(fp, (Uint8 *) &hdr.colorMap, sizeof(hdr.colorMap)) || 1152 !dmf_read_str(fp, (Uint8 *) &hdr.colorMap, sizeof(hdr.colorMap)) ||
1158 !dm_fread_byte(fp, &hdr.reserved) || 1153 !dmf_read_byte(fp, &hdr.reserved) ||
1159 !dm_fread_byte(fp, &hdr.nplanes) || 1154 !dmf_read_byte(fp, &hdr.nplanes) ||
1160 !dm_fread_le16(fp, &hdr.bpl) || 1155 !dmf_read_le16(fp, &hdr.bpl) ||
1161 !dm_fread_le16(fp, &hdr.palInfo) || 1156 !dmf_read_le16(fp, &hdr.palInfo) ||
1162 !dm_fread_le16(fp, &hdr.hScreenSize) || 1157 !dmf_read_le16(fp, &hdr.hScreenSize) ||
1163 !dm_fread_le16(fp, &hdr.vScreenSize) || 1158 !dmf_read_le16(fp, &hdr.vScreenSize) ||
1164 !dm_fread_str(fp, (Uint8 *) &hdr.filler, sizeof(hdr.filler))) 1159 !dmf_read_str(fp, (Uint8 *) &hdr.filler, sizeof(hdr.filler)))
1165 { 1160 {
1166 res = dmError(DMERR_FREAD, 1161 res = dmError(DMERR_FREAD,
1167 "PCX: Could not read image header data.\n"); 1162 "PCX: Could not read image header data.\n");
1168 goto error; 1163 goto error;
1169 } 1164 }
1179 1174
1180 if (hdr.nplanes == 4 && hdr.bitsPerPlane == 4) 1175 if (hdr.nplanes == 4 && hdr.bitsPerPlane == 4)
1181 { 1176 {
1182 dmMsg(2, 1177 dmMsg(2,
1183 "PCX: Probably invalid combination of nplanes and bpp, attempting to fix ..\n"); 1178 "PCX: Probably invalid combination of nplanes and bpp, attempting to fix ..\n");
1184 1179
1185 hdr.bitsPerPlane = 1; 1180 hdr.bitsPerPlane = 1;
1186 } 1181 }
1187 1182
1188 isPaletted = (hdr.bitsPerPlane * hdr.nplanes) <= 8; 1183 isPaletted = (hdr.bitsPerPlane * hdr.nplanes) <= 8;
1189 1184
1255 { 1250 {
1256 res = dmError(DMERR_INVALID_DATA, 1251 res = dmError(DMERR_INVALID_DATA,
1257 "PCX: Error decoding RLE compressed data.\n"); 1252 "PCX: Error decoding RLE compressed data.\n");
1258 goto error; 1253 goto error;
1259 } 1254 }
1260 1255
1261 // Decode bitplanes 1256 // Decode bitplanes
1262 switch (hdr.bitsPerPlane) 1257 switch (hdr.bitsPerPlane)
1263 { 1258 {
1264 case 32: 1259 case 32:
1265 case 24: 1260 case 24:
1309 { 1304 {
1310 int ncolors; 1305 int ncolors;
1311 Uint8 tmpb; 1306 Uint8 tmpb;
1312 BOOL read; 1307 BOOL read;
1313 1308
1314 if (!dm_fread_byte(fp, &tmpb) || tmpb != 0x0C) 1309 if (!dmf_read_byte(fp, &tmpb) || tmpb != 0x0C)
1315 { 1310 {
1316 read = FALSE; 1311 read = FALSE;
1317 ncolors = DMPCX_PAL_COLORS; 1312 ncolors = DMPCX_PAL_COLORS;
1318 } 1313 }
1319 else 1314 else
1360 } 1355 }
1361 1356
1362 1357
1363 int dmReadPCXImage(const char *filename, DMImage **pimg) 1358 int dmReadPCXImage(const char *filename, DMImage **pimg)
1364 { 1359 {
1365 FILE *fp; 1360 DMResource *fp;
1366 int res; 1361 int res;
1367 1362
1368 if ((fp = fopen(filename, "rb")) == NULL) 1363 if ((res = dmf_open_stdio(filename, "rb", &fp)) != DMERR_OK)
1369 { 1364 {
1370 return dmError(DMERR_FOPEN, 1365 return dmError(DMERR_FOPEN,
1371 "PCX: Could not open file '%s' for reading.\n", 1366 "PCX: Could not open file '%s' for reading.\n",
1372 filename); 1367 filename);
1373 } 1368 }
1374 1369
1375 res = dmReadPCXImageFILE(fp, pimg); 1370 res = dmReadPCXImageFILE(fp, pimg);
1376 1371
1377 fclose(fp); 1372 dmf_close(fp);
1378 return res; 1373 return res;
1379 } 1374 }
1380 1375
1381 1376
1382 #define IFF_ID_FORM 0x464F524D // "FORM" 1377 #define IFF_ID_FORM 0x464F524D // "FORM"
1431 DMColor *pal; 1426 DMColor *pal;
1432 BOOL planar; 1427 BOOL planar;
1433 } DMIFF; 1428 } DMIFF;
1434 1429
1435 1430
1436 static BOOL dmReadIFFChunk(FILE *fp, DMIFFChunk *chunk) 1431 static BOOL dmReadIFFChunk(DMResource *fp, DMIFFChunk *chunk)
1437 { 1432 {
1438 if (!dm_fread_be32(fp, &chunk->id) || 1433 if (!dmf_read_be32(fp, &chunk->id) ||
1439 !dm_fread_be32(fp, &chunk->size)) 1434 !dmf_read_be32(fp, &chunk->size))
1440 { 1435 {
1441 dmError(DMERR_FREAD, 1436 dmError(DMERR_FREAD,
1442 "ILBM: Could not read IFF chunk header.\n"); 1437 "ILBM: Could not read IFF chunk header.\n");
1443 return FALSE; 1438 return FALSE;
1444 } 1439 }
1454 chunk->str[3] = (chunk->id) & 0xff; 1449 chunk->str[3] = (chunk->id) & 0xff;
1455 chunk->str[4] = 0; 1450 chunk->str[4] = 0;
1456 return chunk->str; 1451 return chunk->str;
1457 } 1452 }
1458 1453
1459 static int dmSkipIFFChunkRest(FILE *fp, const DMIFFChunk *chunk, const Uint32 used) 1454 static int dmSkipIFFChunkRest(DMResource *fp, const DMIFFChunk *chunk, const Uint32 used)
1460 { 1455 {
1461 if (chunk->size > used) 1456 if (chunk->size > used)
1462 { 1457 {
1463 dmMsg(4, "ILBM: Skipping %d bytes (%d of %d consumed)\n", 1458 dmMsg(4, "ILBM: Skipping %d bytes (%d of %d consumed)\n",
1464 chunk->size - used, used, chunk->size); 1459 chunk->size - used, used, chunk->size);
1465 1460
1466 if (fseeko(fp, chunk->size - used, SEEK_CUR) != 0) 1461 if (dmfseek(fp, chunk->size - used, SEEK_CUR) != 0)
1467 { 1462 {
1468 return dmError(DMERR_FSEEK, 1463 return dmError(DMERR_FSEEK,
1469 "ILBM: Failed to skip chunk end.\n"); 1464 "ILBM: Failed to skip chunk end.\n");
1470 } 1465 }
1471 else 1466 else
1495 1490
1496 return DMERR_OK; 1491 return DMERR_OK;
1497 } 1492 }
1498 1493
1499 1494
1500 static BOOL dmIFFDecodeByteRun1Row(FILE *fp, Uint8 *buf, const size_t bufLen) 1495 static BOOL dmIFFDecodeByteRun1Row(DMResource *fp, Uint8 *buf, const size_t bufLen)
1501 { 1496 {
1502 size_t offs = 0; 1497 size_t offs = 0;
1503 do 1498 do
1504 { 1499 {
1505 Sint8 dcount; 1500 Sint8 dcount;
1506 Uint8 data; 1501 Uint8 data;
1507 1502
1508 if (!dm_fread_byte(fp, (Uint8 *) &dcount)) 1503 if (!dmf_read_byte(fp, (Uint8 *) &dcount))
1509 return FALSE; 1504 return FALSE;
1510 1505
1511 if (dcount == -128) 1506 if (dcount == -128)
1512 { 1507 {
1513 if (!dm_fread_byte(fp, &data)) 1508 if (!dmf_read_byte(fp, &data))
1514 return FALSE; 1509 return FALSE;
1515 } 1510 }
1516 else 1511 else
1517 if (dcount < 0) 1512 if (dcount < 0)
1518 { 1513 {
1519 int count = (-dcount) + 1; 1514 int count = (-dcount) + 1;
1520 if (!dm_fread_byte(fp, &data)) 1515 if (!dmf_read_byte(fp, &data))
1521 return FALSE; 1516 return FALSE;
1522 1517
1523 while (count-- && offs < bufLen) 1518 while (count-- && offs < bufLen)
1524 buf[offs++] = data; 1519 buf[offs++] = data;
1525 } 1520 }
1526 else 1521 else
1527 { 1522 {
1528 int count = dcount + 1; 1523 int count = dcount + 1;
1529 while (count-- && offs < bufLen) 1524 while (count-- && offs < bufLen)
1530 { 1525 {
1531 if (!dm_fread_byte(fp, &data)) 1526 if (!dmf_read_byte(fp, &data))
1532 return FALSE; 1527 return FALSE;
1533 1528
1534 buf[offs++] = data; 1529 buf[offs++] = data;
1535 } 1530 }
1536 } 1531 }
1538 1533
1539 return TRUE; 1534 return TRUE;
1540 } 1535 }
1541 1536
1542 1537
1543 static BOOL dmIFFReadOneRow(FILE *fp, DMIFF *iff, Uint8 *buf, const size_t bufLen) 1538 static BOOL dmIFFReadOneRow(DMResource *fp, DMIFF *iff, Uint8 *buf, const size_t bufLen)
1544 { 1539 {
1545 if (iff->bmhd.compression == IFF_COMP_BYTERUN1) 1540 if (iff->bmhd.compression == IFF_COMP_BYTERUN1)
1546 return dmIFFDecodeByteRun1Row(fp, buf, bufLen); 1541 return dmIFFDecodeByteRun1Row(fp, buf, bufLen);
1547 else 1542 else
1548 return dm_fread_str(fp, buf, bufLen); 1543 return dmf_read_str(fp, buf, bufLen);
1549 } 1544 }
1550 1545
1551 1546
1552 void dmDecodeBitPlane(Uint8 *dp, Uint8 *src, const int width, const int nplane) 1547 void dmDecodeBitPlane(Uint8 *dp, Uint8 *src, const int width, const int nplane)
1553 { 1548 {
1558 dp[xc] |= (data << nplane); 1553 dp[xc] |= (data << nplane);
1559 } 1554 }
1560 } 1555 }
1561 1556
1562 1557
1563 int dmDecodeILBMBody(FILE *fp, DMIFF *iff, DMImage **pimg, Uint32 *read) 1558 int dmDecodeILBMBody(DMResource *fp, DMIFF *iff, DMImage **pimg, Uint32 *read)
1564 { 1559 {
1565 DMImage *img; 1560 DMImage *img;
1566 Uint8 *buf; 1561 Uint8 *buf;
1567 size_t bufLen; 1562 size_t bufLen;
1568 int yc, res = DMERR_OK; 1563 int yc, res = DMERR_OK;
1642 dmFree(buf); 1637 dmFree(buf);
1643 return res; 1638 return res;
1644 } 1639 }
1645 1640
1646 1641
1647 int dmDecodePBMBody(FILE *fp, DMIFF *iff, DMImage **pimg, Uint32 *read) 1642 int dmDecodePBMBody(DMResource *fp, DMIFF *iff, DMImage **pimg, Uint32 *read)
1648 { 1643 {
1649 DMImage *img; 1644 DMImage *img;
1650 int yc, res = DMERR_OK; 1645 int yc, res = DMERR_OK;
1651 1646
1652 *read = 0; 1647 *read = 0;
1678 error: 1673 error:
1679 return res; 1674 return res;
1680 } 1675 }
1681 1676
1682 1677
1683 int dmReadILBMImageFILE(FILE *fp, DMImage **pimg) 1678 int dmReadILBMImageFILE(DMResource *fp, DMImage **pimg)
1684 { 1679 {
1685 Uint32 idILBM; 1680 Uint32 idILBM;
1686 DMIFFChunk chunk; 1681 DMIFFChunk chunk;
1687 DMIFF iff; 1682 DMIFF iff;
1688 Uint32 read; 1683 Uint32 read;
1700 "ILBM: Not a IFF file (%08X vs %08X / %d).\n", 1695 "ILBM: Not a IFF file (%08X vs %08X / %d).\n",
1701 chunk.id, IFF_ID_FORM, chunk.size); 1696 chunk.id, IFF_ID_FORM, chunk.size);
1702 } 1697 }
1703 1698
1704 // Check IFF ILBM signature 1699 // Check IFF ILBM signature
1705 if (!dm_fread_be32(fp, &idILBM) || 1700 if (!dmf_read_be32(fp, &idILBM) ||
1706 (idILBM != IFF_ID_ILBM && idILBM != IFF_ID_PBM)) 1701 (idILBM != IFF_ID_ILBM && idILBM != IFF_ID_PBM))
1707 { 1702 {
1708 return dmError(DMERR_INVALID_DATA, 1703 return dmError(DMERR_INVALID_DATA,
1709 "ILBM: Not a ILBM file.\n"); 1704 "ILBM: Not a ILBM file.\n");
1710 } 1705 }
1711 1706
1712 iff.planar = (idILBM == IFF_ID_ILBM); 1707 iff.planar = (idILBM == IFF_ID_ILBM);
1713 1708
1714 while (!parsed && !feof(fp)) 1709 while (!parsed && !dmfeof(fp))
1715 { 1710 {
1716 if (!dmReadIFFChunk(fp, &chunk)) 1711 if (!dmReadIFFChunk(fp, &chunk))
1717 { 1712 {
1718 return dmError(DMERR_FREAD, 1713 return dmError(DMERR_FREAD,
1719 "ILBM: Error reading IFF ILBM data.\n"); 1714 "ILBM: Error reading IFF ILBM data.\n");
1725 // Check for multiple occurences of BMHD 1720 // Check for multiple occurences of BMHD
1726 if ((res = dmCheckIFFChunk(&iff.chBMHD, &chunk, FALSE, sizeof(iff.bmhd))) != DMERR_OK) 1721 if ((res = dmCheckIFFChunk(&iff.chBMHD, &chunk, FALSE, sizeof(iff.bmhd))) != DMERR_OK)
1727 return res; 1722 return res;
1728 1723
1729 // Read BMHD data 1724 // Read BMHD data
1730 if (!dm_fread_be16(fp, &iff.bmhd.w) || 1725 if (!dmf_read_be16(fp, &iff.bmhd.w) ||
1731 !dm_fread_be16(fp, &iff.bmhd.h) || 1726 !dmf_read_be16(fp, &iff.bmhd.h) ||
1732 !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.x) || 1727 !dmf_read_be16(fp, (Uint16 *) &iff.bmhd.x) ||
1733 !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.y) || 1728 !dmf_read_be16(fp, (Uint16 *) &iff.bmhd.y) ||
1734 !dm_fread_byte(fp, &iff.bmhd.nplanes) || 1729 !dmf_read_byte(fp, &iff.bmhd.nplanes) ||
1735 !dm_fread_byte(fp, &iff.bmhd.masking) || 1730 !dmf_read_byte(fp, &iff.bmhd.masking) ||
1736 !dm_fread_byte(fp, &iff.bmhd.compression) || 1731 !dmf_read_byte(fp, &iff.bmhd.compression) ||
1737 !dm_fread_byte(fp, &iff.bmhd.pad1) || 1732 !dmf_read_byte(fp, &iff.bmhd.pad1) ||
1738 !dm_fread_be16(fp, &iff.bmhd.transp) || 1733 !dmf_read_be16(fp, &iff.bmhd.transp) ||
1739 !dm_fread_byte(fp, &iff.bmhd.xasp) || 1734 !dmf_read_byte(fp, &iff.bmhd.xasp) ||
1740 !dm_fread_byte(fp, &iff.bmhd.yasp) || 1735 !dmf_read_byte(fp, &iff.bmhd.yasp) ||
1741 !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.pagew) || 1736 !dmf_read_be16(fp, (Uint16 *) &iff.bmhd.pagew) ||
1742 !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.pageh)) 1737 !dmf_read_be16(fp, (Uint16 *) &iff.bmhd.pageh))
1743 { 1738 {
1744 return dmError(DMERR_FREAD, 1739 return dmError(DMERR_FREAD,
1745 "ILBM: Error reading BMHD chunk.\n"); 1740 "ILBM: Error reading BMHD chunk.\n");
1746 } 1741 }
1747 1742
1839 parsed = TRUE; 1834 parsed = TRUE;
1840 break; 1835 break;
1841 1836
1842 1837
1843 case IFF_ID_CAMG: 1838 case IFF_ID_CAMG:
1844 if (!dm_fread_be32(fp, &iff.camg)) 1839 if (!dmf_read_be32(fp, &iff.camg))
1845 { 1840 {
1846 return dmError(DMERR_FREAD, 1841 return dmError(DMERR_FREAD,
1847 "ILBM: Error reading CAMG chunk.\n"); 1842 "ILBM: Error reading CAMG chunk.\n");
1848 } 1843 }
1849 1844
1863 default: 1858 default:
1864 { 1859 {
1865 dmMsg(4, "Unknown chunk ID '%s', size %d\n", 1860 dmMsg(4, "Unknown chunk ID '%s', size %d\n",
1866 dmGetIFFChunkID(&chunk), chunk.size); 1861 dmGetIFFChunkID(&chunk), chunk.size);
1867 1862
1868 if (fseeko(fp, chunk.size, SEEK_CUR) != 0) 1863 if (dmfseek(fp, chunk.size, SEEK_CUR) != 0)
1869 { 1864 {
1870 return dmError(DMERR_FSEEK, 1865 return dmError(DMERR_FSEEK,
1871 "ILBM: Error skipping in file."); 1866 "ILBM: Error skipping in file.");
1872 } 1867 }
1873 } 1868 }
1874 break; 1869 break;
1875 } 1870 }
1876 1871
1877 if (chunk.size & 1) 1872 if (chunk.size & 1)
1878 fgetc(fp); 1873 dmfgetc(fp);
1879 } 1874 }
1880 1875
1881 // Set colormap after finishing 1876 // Set colormap after finishing
1882 if (iff.pal != NULL && iff.ncolors > 0 && *pimg != NULL) 1877 if (iff.pal != NULL && iff.ncolors > 0 && *pimg != NULL)
1883 { 1878 {
1918 } 1913 }
1919 1914
1920 1915
1921 int dmReadILBMImage(const char *filename, DMImage **pimg) 1916 int dmReadILBMImage(const char *filename, DMImage **pimg)
1922 { 1917 {
1923 FILE *fp; 1918 DMResource *fp;
1924 int res; 1919 int res;
1925 1920
1926 if ((fp = fopen(filename, "rb")) == NULL) 1921 if ((res = dmf_open_stdio(filename, "rb", &fp)) != DMERR_OK)
1927 { 1922 {
1928 return dmError(DMERR_FOPEN, 1923 return dmError(DMERR_FOPEN,
1929 "ILBM: Could not open file '%s' for reading.\n", 1924 "ILBM: Could not open file '%s' for reading.\n",
1930 filename); 1925 filename);
1931 } 1926 }
1932 1927
1933 res = dmReadILBMImageFILE(fp, pimg); 1928 res = dmReadILBMImageFILE(fp, pimg);
1934 1929
1935 fclose(fp); 1930 dmf_close(fp);
1936 return res; 1931 return res;
1937 } 1932 }
1938 1933
1939 1934
1940 static int fmtProbePNG(const Uint8 *buf, const size_t len) 1935 static int fmtProbePNG(const Uint8 *buf, const size_t len)