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