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