comparison bpgenc.c @ 4:bbd61622856a

Initial implementation of TIFF format read support via libtiff.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 07 Dec 2016 10:37:38 +0200
parents ffcd1967fb5c
children 524eae707ba4
comparison
equal deleted inserted replaced
3:ffcd1967fb5c 4:bbd61622856a
29 #include <math.h> 29 #include <math.h>
30 #include <assert.h> 30 #include <assert.h>
31 31
32 #include <png.h> 32 #include <png.h>
33 #include <jpeglib.h> 33 #include <jpeglib.h>
34 #include <tiffio.h>
34 35
35 #include "bpgenc.h" 36 #include "bpgenc.h"
36 37
37 typedef uint16_t PIXEL; 38 typedef uint16_t PIXEL;
38 39
904 md_next = md->next; 905 md_next = md->next;
905 free(md->buf); 906 free(md->buf);
906 free(md); 907 free(md);
907 md = md_next; 908 md = md_next;
908 } 909 }
910 }
911
912 Image *read_tiff(BPGMetaData **pmd, const char *filename,
913 BPGColorSpaceEnum color_space, int out_bit_depth,
914 int limited_range, int premultiplied_alpha)
915 {
916 TIFF *tif;
917 Image *img = NULL;
918 BPGImageFormatEnum img_format;
919 uint8_t *buf = NULL;
920 uint32_t img_width, img_height;
921 int img_alpha, img_bpp;
922 size_t img_linesize;
923 uint16_t img_depth, img_spp, img_sfmt, img_pconfig;
924 ColorConvertState cvt;
925 RGBConvertFunc *convert_func;
926
927 *pmd = NULL;
928
929 // Open and read TIFF header etc.
930 if ((tif = TIFFOpen(filename, "rb")) == NULL)
931 return NULL;
932
933 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img_width);
934 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img_height);
935 TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &img_spp);
936 TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &img_depth);
937 TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &img_sfmt);
938 TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &img_pconfig);
939
940 // Check basics
941 if ((img_depth != 8 && img_depth != 16) || img_spp > 4)
942 goto err;
943
944 img_linesize = TIFFScanlineSize(tif);
945 img_format = BPG_FORMAT_444;
946 img_bpp = sizeof(uint32_t) * img_depth / 8;
947
948 if (img_spp > 3)
949 {
950 uint16_t img_esmp, *img_esmp_types;
951
952 TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &img_esmp, &img_esmp_types);
953 img_alpha = img_esmp == 1 && img_esmp_types[0] == EXTRASAMPLE_UNASSALPHA;
954 }
955 else
956 img_alpha = 0;
957
958 // Allocate temporary image space
959 buf = (uint8_t *) _TIFFmalloc(img_linesize * img_spp);
960 if (buf == NULL)
961 goto err;
962
963 // Allocate target image
964 img = image_alloc(img_width, img_height, img_format, img_alpha, color_space, out_bit_depth);
965 if (img == NULL)
966 goto err;
967
968 img->limited_range = limited_range;
969 img->premultiplied_alpha = premultiplied_alpha;
970
971 convert_init(&cvt, img_depth, out_bit_depth, color_space, limited_range);
972
973 int idx = img_depth == 16;
974 convert_func = rgb_to_cs[idx][color_space];
975
976 for (int y = 0; y < img->h; y++)
977 {
978 // Read TIFF image to raster
979 if (!TIFFReadScanline(tif, buf, y, 0))
980 goto err;
981
982 // Convert
983 convert_func(&cvt,
984 (PIXEL *)(img->data[0] + y * img->linesize[0]),
985 (PIXEL *)(img->data[1] + y * img->linesize[1]),
986 (PIXEL *)(img->data[2] + y * img->linesize[2]),
987 buf, img->w, img_spp);
988 }
989
990
991 err:
992 if (buf != NULL)
993 _TIFFfree(buf);
994
995 TIFFClose(tif);
996 return img;
909 } 997 }
910 998
911 Image *read_png(BPGMetaData **pmd, 999 Image *read_png(BPGMetaData **pmd,
912 FILE *f, BPGColorSpaceEnum color_space, int out_bit_depth, 1000 FILE *f, BPGColorSpaceEnum color_space, int out_bit_depth,
913 int limited_range, int premultiplied_alpha) 1001 int limited_range, int premultiplied_alpha)
1418 jpeg_destroy_decompress(&cinfo); 1506 jpeg_destroy_decompress(&cinfo);
1419 *pmd = first_md; 1507 *pmd = first_md;
1420 return img; 1508 return img;
1421 } 1509 }
1422 1510
1511 static const char PROBE_TIFF_MAGIC_LE[] = { 'I', 'I', 42, 0 };
1512 static const char PROBE_TIFF_MAGIC_BE[] = { 'M', 'M', 0, 42 };
1513 #define PROBE_BUF_SIZE 8
1514
1423 Image *load_image(BPGMetaData **pmd, const char *infilename, 1515 Image *load_image(BPGMetaData **pmd, const char *infilename,
1424 BPGColorSpaceEnum color_space, int bit_depth, 1516 BPGColorSpaceEnum color_space, int bit_depth,
1425 int limited_range, int premultiplied_alpha) 1517 int limited_range, int premultiplied_alpha)
1426 { 1518 {
1427 FILE *f; 1519 FILE *f;
1439 1531
1440 fseek(f, 0, SEEK_SET); 1532 fseek(f, 0, SEEK_SET);
1441 1533
1442 if (png_sig_cmp(buf, 0, PROBE_BUF_SIZE) == 0) 1534 if (png_sig_cmp(buf, 0, PROBE_BUF_SIZE) == 0)
1443 img = read_png(&md, f, color_space, bit_depth, limited_range, premultiplied_alpha); 1535 img = read_png(&md, f, color_space, bit_depth, limited_range, premultiplied_alpha);
1536 else
1537 if (memcmp(buf, PROBE_TIFF_MAGIC_LE, sizeof(PROBE_TIFF_MAGIC_LE)) == 0 ||
1538 memcmp(buf, PROBE_TIFF_MAGIC_BE, sizeof(PROBE_TIFF_MAGIC_BE)) == 0)
1539 img = read_tiff(&md, infilename, color_space, bit_depth, limited_range, premultiplied_alpha);
1444 else 1540 else
1445 img = read_jpeg(&md, f, bit_depth); 1541 img = read_jpeg(&md, f, bit_depth);
1446 1542
1447 err: 1543 err:
1448 fclose(f); 1544 fclose(f);