File indexing completed on 2025-01-05 03:57:09
0001 /* -*- C++ -*- 0002 * Copyright 2019-2021 LibRaw LLC (info@libraw.org) 0003 * 0004 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, 0005 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. 0006 LibRaw do not use RESTRICTED code from dcraw.c 0007 0008 LibRaw is free software; you can redistribute it and/or modify 0009 it under the terms of the one of two licenses as you choose: 0010 0011 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 0012 (See file LICENSE.LGPL provided in LibRaw distribution archive for details). 0013 0014 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 0015 (See file LICENSE.CDDL provided in LibRaw distribution archive for details). 0016 0017 */ 0018 0019 #include "../../internal/dcraw_defs.h" 0020 #include <vector> 0021 0022 int LibRaw::flip_index(int row, int col) 0023 { 0024 if (flip & 4) 0025 SWAP(row, col); 0026 if (flip & 2) 0027 row = iheight - 1 - row; 0028 if (flip & 1) 0029 col = iwidth - 1 - col; 0030 return row * iwidth + col; 0031 } 0032 0033 void LibRaw::tiff_set(struct tiff_hdr *th, ushort *ntag, ushort tag, 0034 ushort type, int count, int val) 0035 { 0036 struct libraw_tiff_tag *tt; 0037 int c; 0038 0039 tt = (struct libraw_tiff_tag *)(ntag + 1) + (*ntag)++; 0040 tt->val.i = val; 0041 if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_BYTE) && count <= 4) 0042 FORC(4) tt->val.c[c] = val >> (c << 3); 0043 else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII)) 0044 { 0045 count = int(strnlen((char *)th + val, count - 1)) + 1; 0046 if (count <= 4) 0047 FORC(4) tt->val.c[c] = ((char *)th)[val + c]; 0048 } 0049 else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) && count <= 2) 0050 FORC(2) tt->val.s[c] = val >> (c << 4); 0051 tt->count = count; 0052 tt->type = type; 0053 tt->tag = tag; 0054 } 0055 0056 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) 0057 0058 void LibRaw::tiff_head(struct tiff_hdr *th, int full) 0059 { 0060 int c, psize = 0; 0061 struct tm *t; 0062 0063 memset(th, 0, sizeof *th); 0064 th->t_order = htonl(0x4d4d4949) >> 16; 0065 th->magic = 42; 0066 th->ifd = 10; 0067 th->rat[0] = th->rat[2] = 300; 0068 th->rat[1] = th->rat[3] = 1; 0069 FORC(6) th->rat[4 + c] = 1000000; 0070 th->rat[4] *= shutter; 0071 th->rat[6] *= aperture; 0072 th->rat[8] *= focal_len; 0073 strncpy(th->t_desc, desc, 512); 0074 strncpy(th->t_make, make, 64); 0075 strncpy(th->t_model, model, 64); 0076 strcpy(th->soft, "dcraw v" DCRAW_VERSION); 0077 t = localtime(×tamp); 0078 sprintf(th->date, "%04d:%02d:%02d %02d:%02d:%02d", t->tm_year + 1900, 0079 t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); 0080 strncpy(th->t_artist, artist, 64); 0081 if (full) 0082 { 0083 tiff_set(th, &th->ntag, 254, 4, 1, 0); 0084 tiff_set(th, &th->ntag, 256, 4, 1, width); 0085 tiff_set(th, &th->ntag, 257, 4, 1, height); 0086 tiff_set(th, &th->ntag, 258, 3, colors, output_bps); 0087 if (colors > 2) 0088 th->tag[th->ntag - 1].val.i = TOFF(th->bps); 0089 FORC4 th->bps[c] = output_bps; 0090 tiff_set(th, &th->ntag, 259, 3, 1, 1); 0091 tiff_set(th, &th->ntag, 262, 3, 1, 1 + (colors > 1)); 0092 } 0093 tiff_set(th, &th->ntag, 270, 2, 512, TOFF(th->t_desc)); 0094 tiff_set(th, &th->ntag, 271, 2, 64, TOFF(th->t_make)); 0095 tiff_set(th, &th->ntag, 272, 2, 64, TOFF(th->t_model)); 0096 if (full) 0097 { 0098 if (oprof) 0099 psize = ntohl(oprof[0]); 0100 tiff_set(th, &th->ntag, 273, 4, 1, sizeof *th + psize); 0101 tiff_set(th, &th->ntag, 277, 3, 1, colors); 0102 tiff_set(th, &th->ntag, 278, 4, 1, height); 0103 tiff_set(th, &th->ntag, 279, 4, 1, 0104 height * width * colors * output_bps / 8); 0105 } 0106 else 0107 tiff_set(th, &th->ntag, 274, 3, 1, "12435867"[flip] - '0'); 0108 tiff_set(th, &th->ntag, 282, 5, 1, TOFF(th->rat[0])); 0109 tiff_set(th, &th->ntag, 283, 5, 1, TOFF(th->rat[2])); 0110 tiff_set(th, &th->ntag, 284, 3, 1, 1); 0111 tiff_set(th, &th->ntag, 296, 3, 1, 2); 0112 tiff_set(th, &th->ntag, 305, 2, 32, TOFF(th->soft)); 0113 tiff_set(th, &th->ntag, 306, 2, 20, TOFF(th->date)); 0114 tiff_set(th, &th->ntag, 315, 2, 64, TOFF(th->t_artist)); 0115 tiff_set(th, &th->ntag, 34665, 4, 1, TOFF(th->nexif)); 0116 if (psize) 0117 tiff_set(th, &th->ntag, 34675, 7, psize, sizeof *th); 0118 tiff_set(th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4])); 0119 tiff_set(th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6])); 0120 tiff_set(th, &th->nexif, 34855, 3, 1, iso_speed); 0121 tiff_set(th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8])); 0122 if (gpsdata[1]) 0123 { 0124 uchar latref[4] = { (uchar)(gpsdata[29]),0,0,0 }, 0125 lonref[4] = { (uchar)(gpsdata[30]),0,0,0 }; 0126 tiff_set(th, &th->ntag, 34853, 4, 1, TOFF(th->ngps)); 0127 tiff_set(th, &th->ngps, 0, 1, 4, 0x202); 0128 tiff_set(th, &th->ngps, 1, 2, 2, TOFF(latref)); 0129 tiff_set(th, &th->ngps, 2, 5, 3, TOFF(th->gps[0])); 0130 tiff_set(th, &th->ngps, 3, 2, 2, TOFF(lonref)); 0131 tiff_set(th, &th->ngps, 4, 5, 3, TOFF(th->gps[6])); 0132 tiff_set(th, &th->ngps, 5, 1, 1, gpsdata[31]); 0133 tiff_set(th, &th->ngps, 6, 5, 1, TOFF(th->gps[18])); 0134 tiff_set(th, &th->ngps, 7, 5, 3, TOFF(th->gps[12])); 0135 tiff_set(th, &th->ngps, 18, 2, 12, TOFF(th->gps[20])); 0136 tiff_set(th, &th->ngps, 29, 2, 12, TOFF(th->gps[23])); 0137 memcpy(th->gps, gpsdata, sizeof th->gps); 0138 } 0139 } 0140 0141 void LibRaw::jpeg_thumb_writer(FILE *tfp, char *t_humb, int t_humb_length) 0142 { 0143 ushort exif[5]; 0144 struct tiff_hdr th; 0145 fputc(0xff, tfp); 0146 fputc(0xd8, tfp); 0147 if (strcmp(t_humb + 6, "Exif")) 0148 { 0149 memcpy(exif, "\xff\xe1 Exif\0\0", 10); 0150 exif[1] = htons(8 + sizeof th); 0151 fwrite(exif, 1, sizeof exif, tfp); 0152 tiff_head(&th, 0); 0153 fwrite(&th, 1, sizeof th, tfp); 0154 } 0155 fwrite(t_humb + 2, 1, t_humb_length - 2, tfp); 0156 } 0157 void LibRaw::write_ppm_tiff() 0158 { 0159 try 0160 { 0161 struct tiff_hdr th; 0162 ushort *ppm2; 0163 int c, row, col, soff, rstep, cstep; 0164 int perc, val, total, t_white = 0x2000; 0165 0166 perc = width * height * auto_bright_thr; 0167 0168 if (fuji_width) 0169 perc /= 2; 0170 if (!((highlight & ~2) || no_auto_bright)) 0171 for (t_white = c = 0; c < colors; c++) 0172 { 0173 for (val = 0x2000, total = 0; --val > 32;) 0174 if ((total += histogram[c][val]) > perc) 0175 break; 0176 if (t_white < val) 0177 t_white = val; 0178 } 0179 gamma_curve(gamm[0], gamm[1], 2, (t_white << 3) / bright); 0180 iheight = height; 0181 iwidth = width; 0182 if (flip & 4) 0183 SWAP(height, width); 0184 0185 std::vector<uchar> ppm(width * colors * output_bps / 8); 0186 ppm2 = (ushort *)ppm.data(); 0187 if (output_tiff) 0188 { 0189 tiff_head(&th, 1); 0190 fwrite(&th, sizeof th, 1, ofp); 0191 if (oprof) 0192 fwrite(oprof, ntohl(oprof[0]), 1, ofp); 0193 } 0194 else if (colors > 3) 0195 { 0196 if(imgdata.params.output_flags & LIBRAW_OUTPUT_FLAGS_PPMMETA) 0197 fprintf(ofp, 0198 "P7\n# EXPTIME=%0.5f\n# TIMESTAMP=%d\n# ISOSPEED=%d\n" 0199 "# APERTURE=%0.1f\n# FOCALLEN=%0.1f\n# MAKE=%s\n# MODEL=%s\n" 0200 "WIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", 0201 shutter, (int)timestamp, (int)iso_speed,aperture, 0202 focal_len, make, model, 0203 width, height, colors, (1 << output_bps) - 1, cdesc); 0204 else 0205 fprintf( 0206 ofp, 0207 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", 0208 width, height, colors, (1 << output_bps) - 1, cdesc); 0209 } 0210 else 0211 { 0212 if(imgdata.params.output_flags & LIBRAW_OUTPUT_FLAGS_PPMMETA) 0213 fprintf(ofp, "P%d\n# EXPTIME=%0.5f\n# TIMESTAMP=%d\n" 0214 "# ISOSPEED=%d\n# APERTURE=%0.1f\n# FOCALLEN=%0.1f\n" 0215 "# MAKE=%s\n# MODEL=%s\n%d %d\n%d\n", 0216 colors/2+5, 0217 shutter, (int)timestamp, (int)iso_speed,aperture,focal_len, 0218 make,model, 0219 width, height, (1 << output_bps)-1); 0220 else 0221 fprintf(ofp, "P%d\n%d %d\n%d\n", colors / 2 + 5, width, height, 0222 (1 << output_bps) - 1); 0223 } 0224 soff = flip_index(0, 0); 0225 cstep = flip_index(0, 1) - soff; 0226 rstep = flip_index(1, 0) - flip_index(0, width); 0227 for (row = 0; row < height; row++, soff += rstep) 0228 { 0229 for (col = 0; col < width; col++, soff += cstep) 0230 if (output_bps == 8) 0231 FORCC ppm[col * colors + c] = curve[image[soff][c]] >> 8; 0232 else 0233 FORCC ppm2[col * colors + c] = curve[image[soff][c]]; 0234 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa) 0235 libraw_swab(ppm2, width * colors * 2); 0236 fwrite(ppm.data(), colors * output_bps / 8, width, ofp); 0237 } 0238 } 0239 catch (...) 0240 { 0241 throw LIBRAW_EXCEPTION_ALLOC; // rethrow 0242 } 0243 } 0244 #if 0 0245 void LibRaw::ppm_thumb() 0246 { 0247 try 0248 { 0249 thumb_length = thumb_width * thumb_height * 3; 0250 std::vector<char> thumb(thumb_length); 0251 fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); 0252 fread(thumb.data(), 1, thumb_length, ifp); 0253 fwrite(thumb.data(), 1, thumb_length, ofp); 0254 } 0255 catch (...) 0256 { 0257 throw LIBRAW_EXCEPTION_ALLOC; // rethrow 0258 } 0259 } 0260 0261 void LibRaw::ppm16_thumb() 0262 { 0263 try 0264 { 0265 unsigned i; 0266 thumb_length = thumb_width * thumb_height * 3; 0267 std::vector<char> thumb(thumb_length * 2, 0); 0268 read_shorts((ushort *)thumb.data(), thumb_length); 0269 for (i = 0; i < thumb_length; i++) 0270 thumb[i] = ((ushort *)thumb.data())[i] >> 8; 0271 fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); 0272 fwrite(thumb.data(), 1, thumb_length, ofp); 0273 } 0274 catch (...) 0275 { 0276 throw LIBRAW_EXCEPTION_ALLOC; // rethrow 0277 } 0278 } 0279 0280 void LibRaw::layer_thumb() 0281 { 0282 try 0283 { 0284 unsigned int i; 0285 int c; 0286 char map[][4] = { "012", "102" }; 0287 0288 colors = thumb_misc >> 5 & 7; 0289 thumb_length = thumb_width * thumb_height; 0290 std::vector<char> thumb(colors * thumb_length, 0); 0291 fprintf(ofp, "P%d\n%d %d\n255\n", 5 + (colors >> 1), thumb_width, 0292 thumb_height); 0293 fread(thumb.data(), thumb_length, colors, ifp); 0294 for (i = 0; i < thumb_length; i++) 0295 FORCC putc(thumb[i + thumb_length * (map[thumb_misc >> 8][c] - '0')], ofp); 0296 } 0297 catch (...) 0298 { 0299 throw LIBRAW_EXCEPTION_ALLOC; // rethrow 0300 } 0301 } 0302 0303 void LibRaw::rollei_thumb() 0304 { 0305 try 0306 { 0307 unsigned i; 0308 thumb_length = thumb_width * thumb_height; 0309 std::vector<ushort> thumb(thumb_length, 0); 0310 fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); 0311 read_shorts(thumb.data(), thumb_length); 0312 for (i = 0; i < thumb_length; i++) 0313 { 0314 putc(thumb[i] << 3, ofp); 0315 putc(thumb[i] >> 5 << 2, ofp); 0316 putc(thumb[i] >> 11 << 3, ofp); 0317 } 0318 } 0319 catch (...) 0320 { 0321 throw LIBRAW_EXCEPTION_ALLOC; // rethrow 0322 } 0323 } 0324 0325 void LibRaw::jpeg_thumb() 0326 { 0327 try 0328 { 0329 std::vector<char> thumb(thumb_length); 0330 fread(thumb.data(), 1, thumb_length, ifp); 0331 jpeg_thumb_writer(ofp, thumb.data(), thumb_length); 0332 } 0333 catch (...) 0334 { 0335 throw LIBRAW_EXCEPTION_ALLOC; // rethrow 0336 } 0337 } 0338 #endif