Mercurial > hg > forks > libbpg
comparison bpgenc.c @ 11:e70eb0e6acd5
Add support for indexed palette TIFFs, at least some of them.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 08 Dec 2016 21:40:44 +0200 |
parents | d04d9e3a77d0 |
children | 9b00d4206f99 |
comparison
equal
deleted
inserted
replaced
10:d04d9e3a77d0 | 11:e70eb0e6acd5 |
---|---|
955 BPGImageFormatEnum img_format; | 955 BPGImageFormatEnum img_format; |
956 uint8_t *buf = NULL, *tmp_buf = NULL; | 956 uint8_t *buf = NULL, *tmp_buf = NULL; |
957 uint32_t img_width, img_height, tmp_len; | 957 uint32_t img_width, img_height, tmp_len; |
958 int img_alpha, err_spp = 0; | 958 int img_alpha, err_spp = 0; |
959 size_t img_linesize; | 959 size_t img_linesize; |
960 uint16_t img_depth, img_spp, img_pconfig, img_pmetric; | 960 uint16_t img_depth, img_spp, img_pconfig, img_pmetric, |
961 *buf2 = NULL, *img_colormap_r, *img_colormap_g, *img_colormap_b; | |
961 ColorConvertState cvt; | 962 ColorConvertState cvt; |
962 RGBConvertFunc *convert_func; | 963 RGBConvertFunc *convert_func; |
963 | 964 |
964 // Open and read TIFF header etc. | 965 // Open and read TIFF header etc. |
965 if ((tif = TIFFOpen(filename, "rb")) == NULL) | 966 if ((tif = TIFFOpen(filename, "rb")) == NULL) |
987 img_format = BPG_FORMAT_444; | 988 img_format = BPG_FORMAT_444; |
988 if (img_spp < 3) | 989 if (img_spp < 3) |
989 err_spp = 1; | 990 err_spp = 1; |
990 break; | 991 break; |
991 | 992 |
993 case PHOTOMETRIC_PALETTE: | |
994 img_format = BPG_FORMAT_444; | |
995 if (img_spp != 1) | |
996 err_spp = 1; | |
997 | |
998 if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &img_colormap_r, &img_colormap_g, &img_colormap_b)) | |
999 { | |
1000 fprintf(stderr, "TIFF with palette is missing colormap entry!\n"); | |
1001 goto err; | |
1002 } | |
1003 break; | |
1004 | |
992 default: | 1005 default: |
993 fprintf(stderr, "TIFF file has unsupported photometric interpretation %d!\n", img_pmetric); | 1006 fprintf(stderr, "TIFF file has unsupported photometric interpretation %d!\n", img_pmetric); |
994 goto err; | 1007 goto err; |
995 } | 1008 } |
996 | 1009 |
1005 fprintf(stderr, "TIFF file has unsupported depth %d (not 8 or 16)!\n", img_depth); | 1018 fprintf(stderr, "TIFF file has unsupported depth %d (not 8 or 16)!\n", img_depth); |
1006 goto err; | 1019 goto err; |
1007 } | 1020 } |
1008 | 1021 |
1009 img_linesize = TIFFScanlineSize(tif); | 1022 img_linesize = TIFFScanlineSize(tif); |
1010 img_format = BPG_FORMAT_444; | |
1011 img_bpp = sizeof(uint32_t) * img_depth / 8; | |
1012 | 1023 |
1013 if (img_spp > 3) | 1024 if (img_spp > 3) |
1014 { | 1025 { |
1015 uint16_t img_esmp, *img_esmp_types; | 1026 uint16_t img_esmp, *img_esmp_types; |
1016 | 1027 |
1022 | 1033 |
1023 // Allocate temporary image space | 1034 // Allocate temporary image space |
1024 buf = (uint8_t *) _TIFFmalloc(img_linesize * img_spp); | 1035 buf = (uint8_t *) _TIFFmalloc(img_linesize * img_spp); |
1025 if (buf == NULL) | 1036 if (buf == NULL) |
1026 goto err; | 1037 goto err; |
1038 | |
1039 if (img_pmetric == PHOTOMETRIC_PALETTE) | |
1040 { | |
1041 // For indexed palette images we need a secondary RGB conversion buffer | |
1042 buf2 = (uint16_t *) malloc(img_width * 3 * sizeof(uint16_t)); | |
1043 if (buf2 == NULL) | |
1044 goto err; | |
1045 | |
1046 // Force 16bit depth and samples per pixel 3 as the | |
1047 // TIFF colormap/palette has 16bit R, G, B entries. | |
1048 img_spp = 3; | |
1049 img_depth = 16; | |
1050 } | |
1027 | 1051 |
1028 // Allocate target image | 1052 // Allocate target image |
1029 img = image_alloc(img_width, img_height, img_format, img_alpha, color_space, out_bit_depth); | 1053 img = image_alloc(img_width, img_height, img_format, img_alpha, color_space, out_bit_depth); |
1030 if (img == NULL) | 1054 if (img == NULL) |
1031 goto err; | 1055 goto err; |
1042 { | 1066 { |
1043 // Read TIFF image to raster | 1067 // Read TIFF image to raster |
1044 if (!TIFFReadScanline(tif, buf, y, 0)) | 1068 if (!TIFFReadScanline(tif, buf, y, 0)) |
1045 goto err; | 1069 goto err; |
1046 | 1070 |
1047 // Convert | 1071 // Convert the scanline data |
1048 convert_func(&cvt, | 1072 switch (img_pmetric) |
1049 (PIXEL *)(img->data[0] + y * img->linesize[0]), | |
1050 (PIXEL *)(img->data[1] + y * img->linesize[1]), | |
1051 (PIXEL *)(img->data[2] + y * img->linesize[2]), | |
1052 buf, img->w, img_spp); | |
1053 | |
1054 if (img_alpha) | |
1055 { | 1073 { |
1056 if (idx) | 1074 case PHOTOMETRIC_PALETTE: |
1057 { | 1075 for (int x = 0, offs = 0; x < img->w; x++) |
1058 gray16_to_gray(&cvt, | 1076 { |
1059 (PIXEL *)(img->data[3] + y * img->linesize[3]), | 1077 buf2[offs++] = img_colormap_r[buf[x]]; |
1060 ((uint16_t *) buf) + 3, img->w, 4); | 1078 buf2[offs++] = img_colormap_g[buf[x]]; |
1061 } | 1079 buf2[offs++] = img_colormap_b[buf[x]]; |
1062 else | 1080 } |
1063 { | 1081 convert_func(&cvt, |
1064 gray8_to_gray(&cvt, | 1082 (PIXEL *)(img->data[0] + y * img->linesize[0]), |
1065 (PIXEL *)(img->data[3] + y * img->linesize[3]), | 1083 (PIXEL *)(img->data[1] + y * img->linesize[1]), |
1066 ((uint8_t *) buf) + 3, img->w, 4); | 1084 (PIXEL *)(img->data[2] + y * img->linesize[2]), |
1067 } | 1085 buf2, img->w, img_spp); |
1086 break; | |
1087 | |
1088 case PHOTOMETRIC_RGB: | |
1089 convert_func(&cvt, | |
1090 (PIXEL *)(img->data[0] + y * img->linesize[0]), | |
1091 (PIXEL *)(img->data[1] + y * img->linesize[1]), | |
1092 (PIXEL *)(img->data[2] + y * img->linesize[2]), | |
1093 buf, img->w, img_spp); | |
1094 | |
1095 if (img_alpha) | |
1096 { | |
1097 if (idx) | |
1098 { | |
1099 gray16_to_gray(&cvt, | |
1100 (PIXEL *)(img->data[3] + y * img->linesize[3]), | |
1101 ((uint16_t *) buf) + 3, img->w, 4); | |
1102 } | |
1103 else | |
1104 { | |
1105 gray8_to_gray(&cvt, | |
1106 (PIXEL *)(img->data[3] + y * img->linesize[3]), | |
1107 ((uint8_t *) buf) + 3, img->w, 4); | |
1108 } | |
1109 } | |
1110 break; | |
1068 } | 1111 } |
1069 } | 1112 } |
1070 | 1113 |
1071 // Get meta data | 1114 // Get meta data |
1072 if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &tmp_len, &tmp_buf)) | 1115 if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &tmp_len, &tmp_buf)) |
1076 add_md_contents(pmd, BPG_EXTENSION_TAG_XMP, tmp_len, tmp_buf); | 1119 add_md_contents(pmd, BPG_EXTENSION_TAG_XMP, tmp_len, tmp_buf); |
1077 | 1120 |
1078 err: | 1121 err: |
1079 if (buf != NULL) | 1122 if (buf != NULL) |
1080 _TIFFfree(buf); | 1123 _TIFFfree(buf); |
1124 | |
1125 if (buf2 != NULL) | |
1126 free(buf2); | |
1081 | 1127 |
1082 TIFFClose(tif); | 1128 TIFFClose(tif); |
1083 return img; | 1129 return img; |
1084 } | 1130 } |
1085 | 1131 |