comparison tools/libgfx.c @ 2092:614b161c0aa5

Initial support for reading PPM/PGM.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 28 Feb 2019 12:30:21 +0200
parents 3b3acb6b4ba0
children d17512dbb4ef
comparison
equal deleted inserted replaced
2091:3b3acb6b4ba0 2092:614b161c0aa5
104 104
105 int dmImageGetBytesPerPixel(const int format) 105 int dmImageGetBytesPerPixel(const int format)
106 { 106 {
107 switch (format) 107 switch (format)
108 { 108 {
109 case DM_COLFMT_GRAYSCALE : return 1;
109 case DM_COLFMT_PALETTE : return 1; 110 case DM_COLFMT_PALETTE : return 1;
110 case DM_COLFMT_RGB : return 3; 111 case DM_COLFMT_RGB : return 3;
111 case DM_COLFMT_RGBA : return 4; 112 case DM_COLFMT_RGBA : return 4;
112 default : return -1; 113 default : return -1;
113 } 114 }
241 qr, qg, qb, qa; 242 qr, qg, qb, qa;
242 243
243 switch (spec->format) 244 switch (spec->format)
244 { 245 {
245 case DM_COLFMT_PALETTE: 246 case DM_COLFMT_PALETTE:
247 case DM_COLFMT_GRAYSCALE:
246 for (xscale = 0; xscale < spec->scaleX; xscale++) 248 for (xscale = 0; xscale < spec->scaleX; xscale++)
247 *ptr1++ = c; 249 *ptr1++ = c;
248 break; 250 break;
249 251
250 case DM_COLFMT_RGBA: 252 case DM_COLFMT_RGBA:
509 511
510 512
511 int dmWritePPMImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec) 513 int dmWritePPMImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec)
512 { 514 {
513 DMImageConvSpec tmpSpec; 515 DMImageConvSpec tmpSpec;
516 char *tmpFmt;
517
518 memcpy(&tmpSpec, spec, sizeof(DMImageConvSpec));
519
520 switch (spec->format)
521 {
522 case DM_COLFMT_RGB:
523 case DM_COLFMT_RGBA:
524 case DM_COLFMT_PALETTE:
525 tmpSpec.format = DM_COLFMT_RGB;
526 tmpFmt = "6";
527 break;
528
529 case DM_COLFMT_GRAYSCALE:
530 tmpFmt = "5";
531 break;
532
533 default:
534 return dmError(DMERR_NOT_SUPPORTED,
535 "PPM: Not a supported color format for PPM/PGM format image.\n");
536 }
514 537
515 // Write PPM header 538 // Write PPM header
516 char *tmp = dm_strdup_printf( 539 char *tmp = dm_strdup_printf(
517 "P6\n%d %d\n255\n", 540 "P%s\n%d %d\n255\n",
541 tmpFmt,
518 img->width * spec->scaleX, 542 img->width * spec->scaleX,
519 img->height * spec->scaleY); 543 img->height * spec->scaleY);
520 544
521 if (tmp == NULL) 545 if (tmp == NULL)
522 return DMERR_MALLOC; 546 return DMERR_MALLOC;
523 547
524 dmfputs(tmp, fp); 548 dmfputs(tmp, fp);
525 dmFree(tmp); 549 dmFree(tmp);
526 550
527 // Write image data 551 // Write image data
528 memcpy(&tmpSpec, spec, sizeof(DMImageConvSpec));
529 tmpSpec.format = DM_COLFMT_RGB;
530 return dmWriteImageData(img, (void *) fp, dmWritePPMRow, &tmpSpec); 552 return dmWriteImageData(img, (void *) fp, dmWritePPMRow, &tmpSpec);
553 }
554
555
556 int dmReadPPMImage(DMResource *fp, DMImage **pimg)
557 {
558 DMImage *img = NULL;
559 unsigned int width, height;
560 int itype, res = DMERR_OK;
561 char hdr1[8], hdr2[32], hdr3[16];
562
563 // Read PPM header
564 if (dmfgets(hdr1, sizeof(hdr1), fp) == NULL ||
565 dmfgets(hdr2, sizeof(hdr2), fp) == NULL ||
566 dmfgets(hdr3, sizeof(hdr3), fp) == NULL)
567 {
568 res = dmError(DMERR_FREAD,
569 "PPM: Could not read image header data.\n");
570 goto error;
571 }
572
573 if (hdr1[0] != 'P' || !isdigit(hdr1[1]) ||
574 !isdigit(hdr2[0]) || !isdigit(hdr3[0]))
575 {
576 res = dmError(DMERR_NOT_SUPPORTED,
577 "PPM: Not a supported PPM/PGM format image.\n");
578 goto error;
579 }
580
581 switch (hdr1[1])
582 {
583 case '6': itype = DM_COLFMT_RGB; break;
584 case '5': itype = DM_COLFMT_GRAYSCALE; break;
585 default:
586 res = dmError(DMERR_NOT_SUPPORTED,
587 "PPM: Unsupported PPM/PGM subtype.\n");
588 goto error;
589 }
590
591 if (sscanf(hdr2, "%u %u", &width, &height) != 2)
592 {
593 res = dmError(DMERR_INVALID_DATA,
594 "PPM: Invalid PPM/PGM image dimensions.\n");
595 goto error;
596 }
597
598 if ((*pimg = img = dmImageAlloc(width, height, itype, -1)) == NULL)
599 {
600 res = dmError(DMERR_MALLOC,
601 "PPM: Could not allocate image data.\n");
602 goto error;
603 }
604
605 if (dmf_read_str(fp, img->data, img->size))
606 {
607 res = dmError(DMERR_FREAD,
608 "PPM: Could not read image data.\n");
609 goto error;
610 }
611
612 error:
613
614 return res;
615 }
616
617
618 static int fmtProbePPM(const Uint8 *buf, const size_t len)
619 {
620 if (len > 32 &&
621 buf[0] == 'P' &&
622 buf[1] == '5' &&
623 buf[2] == 0x0a && isdigit(buf[3]))
624 return DM_PROBE_SCORE_MAX;
625
626 return DM_PROBE_SCORE_FALSE;
531 } 627 }
532 628
533 629
534 #ifdef DM_USE_LIBPNG 630 #ifdef DM_USE_LIBPNG
535 static int fmtProbePNG(const Uint8 *buf, const size_t len) 631 static int fmtProbePNG(const Uint8 *buf, const size_t len)
2516 fmtProbePNG, dmReadPNGImage, dmWritePNGImage, 2612 fmtProbePNG, dmReadPNGImage, dmWritePNGImage,
2517 }, 2613 },
2518 #endif 2614 #endif
2519 { 2615 {
2520 "ppm", "Portable PixMap", 2616 "ppm", "Portable PixMap",
2521 DM_IMGFMT_PPM, DM_FMT_WR, 2617 DM_IMGFMT_PPM, DM_FMT_RDWR,
2522 NULL, NULL, dmWritePPMImage, 2618 fmtProbePPM, dmReadPPMImage, dmWritePPMImage,
2523 }, 2619 },
2524 { 2620 {
2525 "pcx", "Z-Soft Paintbrush", 2621 "pcx", "Z-Soft Paintbrush",
2526 DM_IMGFMT_PCX, DM_FMT_RDWR, 2622 DM_IMGFMT_PCX, DM_FMT_RDWR,
2527 fmtProbePCX, dmReadPCXImage, dmWritePCXImage, 2623 fmtProbePCX, dmReadPCXImage, dmWritePCXImage,