1 /* -*- C++ -*-
2 * Copyright 2019-2020 LibRaw LLC (info@libraw.org)
3 *
4 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
5 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
6 LibRaw do not use RESTRICTED code from dcraw.c
7
8 LibRaw is free software; you can redistribute it and/or modify
9 it under the terms of the one of two licenses as you choose:
10
11 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12 (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13
14 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15 (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16
17 */
18
19 #include "../../internal/dcraw_defs.h"
20
flip_index(int row,int col)21 int LibRaw::flip_index(int row, int col)
22 {
23 if (flip & 4)
24 SWAP(row, col);
25 if (flip & 2)
26 row = iheight - 1 - row;
27 if (flip & 1)
28 col = iwidth - 1 - col;
29 return row * iwidth + col;
30 }
31
tiff_set(struct tiff_hdr * th,ushort * ntag,ushort tag,ushort type,int count,int val)32 void LibRaw::tiff_set(struct tiff_hdr *th, ushort *ntag, ushort tag,
33 ushort type, int count, int val)
34 {
35 struct libraw_tiff_tag *tt;
36 int c;
37
38 tt = (struct libraw_tiff_tag *)(ntag + 1) + (*ntag)++;
39 tt->val.i = val;
40 if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_BYTE) && count <= 4)
41 FORC(4) tt->val.c[c] = val >> (c << 3);
42 else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_ASCII))
43 {
44 count = strnlen((char *)th + val, count - 1) + 1;
45 if (count <= 4)
46 FORC(4) tt->val.c[c] = ((char *)th)[val + c];
47 }
48 else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) && count <= 2)
49 FORC(2) tt->val.s[c] = val >> (c << 4);
50 tt->count = count;
51 tt->type = type;
52 tt->tag = tag;
53 }
54
55 #define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
56
tiff_head(struct tiff_hdr * th,int full)57 void LibRaw::tiff_head(struct tiff_hdr *th, int full)
58 {
59 int c, psize = 0;
60 struct tm *t;
61
62 memset(th, 0, sizeof *th);
63 th->t_order = htonl(0x4d4d4949) >> 16;
64 th->magic = 42;
65 th->ifd = 10;
66 th->rat[0] = th->rat[2] = 300;
67 th->rat[1] = th->rat[3] = 1;
68 FORC(6) th->rat[4 + c] = 1000000;
69 th->rat[4] *= shutter;
70 th->rat[6] *= aperture;
71 th->rat[8] *= focal_len;
72 strncpy(th->t_desc, desc, 512);
73 strncpy(th->t_make, make, 64);
74 strncpy(th->t_model, model, 64);
75 strcpy(th->soft, "dcraw v" DCRAW_VERSION);
76 t = localtime(×tamp);
77 sprintf(th->date, "%04d:%02d:%02d %02d:%02d:%02d", t->tm_year + 1900,
78 t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
79 strncpy(th->t_artist, artist, 64);
80 if (full)
81 {
82 tiff_set(th, &th->ntag, 254, 4, 1, 0);
83 tiff_set(th, &th->ntag, 256, 4, 1, width);
84 tiff_set(th, &th->ntag, 257, 4, 1, height);
85 tiff_set(th, &th->ntag, 258, 3, colors, output_bps);
86 if (colors > 2)
87 th->tag[th->ntag - 1].val.i = TOFF(th->bps);
88 FORC4 th->bps[c] = output_bps;
89 tiff_set(th, &th->ntag, 259, 3, 1, 1);
90 tiff_set(th, &th->ntag, 262, 3, 1, 1 + (colors > 1));
91 }
92 tiff_set(th, &th->ntag, 270, 2, 512, TOFF(th->t_desc));
93 tiff_set(th, &th->ntag, 271, 2, 64, TOFF(th->t_make));
94 tiff_set(th, &th->ntag, 272, 2, 64, TOFF(th->t_model));
95 if (full)
96 {
97 if (oprof)
98 psize = ntohl(oprof[0]);
99 tiff_set(th, &th->ntag, 273, 4, 1, sizeof *th + psize);
100 tiff_set(th, &th->ntag, 277, 3, 1, colors);
101 tiff_set(th, &th->ntag, 278, 4, 1, height);
102 tiff_set(th, &th->ntag, 279, 4, 1,
103 height * width * colors * output_bps / 8);
104 }
105 else
106 tiff_set(th, &th->ntag, 274, 3, 1, "12435867"[flip] - '0');
107 tiff_set(th, &th->ntag, 282, 5, 1, TOFF(th->rat[0]));
108 tiff_set(th, &th->ntag, 283, 5, 1, TOFF(th->rat[2]));
109 tiff_set(th, &th->ntag, 284, 3, 1, 1);
110 tiff_set(th, &th->ntag, 296, 3, 1, 2);
111 tiff_set(th, &th->ntag, 305, 2, 32, TOFF(th->soft));
112 tiff_set(th, &th->ntag, 306, 2, 20, TOFF(th->date));
113 tiff_set(th, &th->ntag, 315, 2, 64, TOFF(th->t_artist));
114 tiff_set(th, &th->ntag, 34665, 4, 1, TOFF(th->nexif));
115 if (psize)
116 tiff_set(th, &th->ntag, 34675, 7, psize, sizeof *th);
117 tiff_set(th, &th->nexif, 33434, 5, 1, TOFF(th->rat[4]));
118 tiff_set(th, &th->nexif, 33437, 5, 1, TOFF(th->rat[6]));
119 tiff_set(th, &th->nexif, 34855, 3, 1, iso_speed);
120 tiff_set(th, &th->nexif, 37386, 5, 1, TOFF(th->rat[8]));
121 if (gpsdata[1])
122 {
123 uchar latref[4] = { (uchar)(gpsdata[29]),0,0,0 },
124 lonref[4] = { (uchar)(gpsdata[30]),0,0,0 };
125 tiff_set(th, &th->ntag, 34853, 4, 1, TOFF(th->ngps));
126 tiff_set(th, &th->ngps, 0, 1, 4, 0x202);
127 tiff_set(th, &th->ngps, 1, 2, 2, TOFF(latref));
128 tiff_set(th, &th->ngps, 2, 5, 3, TOFF(th->gps[0]));
129 tiff_set(th, &th->ngps, 3, 2, 2, TOFF(lonref));
130 tiff_set(th, &th->ngps, 4, 5, 3, TOFF(th->gps[6]));
131 tiff_set(th, &th->ngps, 5, 1, 1, gpsdata[31]);
132 tiff_set(th, &th->ngps, 6, 5, 1, TOFF(th->gps[18]));
133 tiff_set(th, &th->ngps, 7, 5, 3, TOFF(th->gps[12]));
134 tiff_set(th, &th->ngps, 18, 2, 12, TOFF(th->gps[20]));
135 tiff_set(th, &th->ngps, 29, 2, 12, TOFF(th->gps[23]));
136 memcpy(th->gps, gpsdata, sizeof th->gps);
137 }
138 }
139
jpeg_thumb_writer(FILE * tfp,char * t_humb,int t_humb_length)140 void LibRaw::jpeg_thumb_writer(FILE *tfp, char *t_humb, int t_humb_length)
141 {
142 ushort exif[5];
143 struct tiff_hdr th;
144 fputc(0xff, tfp);
145 fputc(0xd8, tfp);
146 if (strcmp(t_humb + 6, "Exif"))
147 {
148 memcpy(exif, "\xff\xe1 Exif\0\0", 10);
149 exif[1] = htons(8 + sizeof th);
150 fwrite(exif, 1, sizeof exif, tfp);
151 tiff_head(&th, 0);
152 fwrite(&th, 1, sizeof th, tfp);
153 }
154 fwrite(t_humb + 2, 1, t_humb_length - 2, tfp);
155 }
write_ppm_tiff()156 void LibRaw::write_ppm_tiff()
157 {
158 struct tiff_hdr th;
159 uchar *ppm;
160 ushort *ppm2;
161 int c, row, col, soff, rstep, cstep;
162 int perc, val, total, t_white = 0x2000;
163
164 perc = width * height * auto_bright_thr;
165
166 if (fuji_width)
167 perc /= 2;
168 if (!((highlight & ~2) || no_auto_bright))
169 for (t_white = c = 0; c < colors; c++)
170 {
171 for (val = 0x2000, total = 0; --val > 32;)
172 if ((total += histogram[c][val]) > perc)
173 break;
174 if (t_white < val)
175 t_white = val;
176 }
177 gamma_curve(gamm[0], gamm[1], 2, (t_white << 3) / bright);
178 iheight = height;
179 iwidth = width;
180 if (flip & 4)
181 SWAP(height, width);
182 ppm = (uchar *)calloc(width, colors * output_bps / 8);
183 ppm2 = (ushort *)ppm;
184 merror(ppm, "write_ppm_tiff()");
185 if (output_tiff)
186 {
187 tiff_head(&th, 1);
188 fwrite(&th, sizeof th, 1, ofp);
189 if (oprof)
190 fwrite(oprof, ntohl(oprof[0]), 1, ofp);
191 }
192 else if (colors > 3)
193 fprintf(
194 ofp,
195 "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
196 width, height, colors, (1 << output_bps) - 1, cdesc);
197 else
198 fprintf(ofp, "P%d\n%d %d\n%d\n", colors / 2 + 5, width, height,
199 (1 << output_bps) - 1);
200 soff = flip_index(0, 0);
201 cstep = flip_index(0, 1) - soff;
202 rstep = flip_index(1, 0) - flip_index(0, width);
203 for (row = 0; row < height; row++, soff += rstep)
204 {
205 for (col = 0; col < width; col++, soff += cstep)
206 if (output_bps == 8)
207 FORCC ppm[col * colors + c] = curve[image[soff][c]] >> 8;
208 else
209 FORCC ppm2[col * colors + c] = curve[image[soff][c]];
210 if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
211 swab((char *)ppm2, (char *)ppm2, width * colors * 2);
212 fwrite(ppm, colors * output_bps / 8, width, ofp);
213 }
214 free(ppm);
215 }
ppm_thumb()216 void LibRaw::ppm_thumb()
217 {
218 char *thumb;
219 thumb_length = thumb_width * thumb_height * 3;
220 thumb = (char *)malloc(thumb_length);
221 merror(thumb, "ppm_thumb()");
222 fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
223 fread(thumb, 1, thumb_length, ifp);
224 fwrite(thumb, 1, thumb_length, ofp);
225 free(thumb);
226 }
227
ppm16_thumb()228 void LibRaw::ppm16_thumb()
229 {
230 unsigned i;
231 char *thumb;
232 thumb_length = thumb_width * thumb_height * 3;
233 thumb = (char *)calloc(thumb_length, 2);
234 merror(thumb, "ppm16_thumb()");
235 read_shorts((ushort *)thumb, thumb_length);
236 for (i = 0; i < thumb_length; i++)
237 thumb[i] = ((ushort *)thumb)[i] >> 8;
238 fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
239 fwrite(thumb, 1, thumb_length, ofp);
240 free(thumb);
241 }
242
layer_thumb()243 void LibRaw::layer_thumb()
244 {
245 unsigned int i;
246 int c;
247 char *thumb, map[][4] = {"012", "102"};
248
249 colors = thumb_misc >> 5 & 7;
250 thumb_length = thumb_width * thumb_height;
251 thumb = (char *)calloc(colors, thumb_length);
252 merror(thumb, "layer_thumb()");
253 fprintf(ofp, "P%d\n%d %d\n255\n", 5 + (colors >> 1), thumb_width,
254 thumb_height);
255 fread(thumb, thumb_length, colors, ifp);
256 for (i = 0; i < thumb_length; i++)
257 FORCC putc(thumb[i + thumb_length * (map[thumb_misc >> 8][c] - '0')], ofp);
258 free(thumb);
259 }
260
rollei_thumb()261 void LibRaw::rollei_thumb()
262 {
263 unsigned i;
264 ushort *thumb;
265
266 thumb_length = thumb_width * thumb_height;
267 thumb = (ushort *)calloc(thumb_length, 2);
268 merror(thumb, "rollei_thumb()");
269 fprintf(ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height);
270 read_shorts(thumb, thumb_length);
271 for (i = 0; i < thumb_length; i++)
272 {
273 putc(thumb[i] << 3, ofp);
274 putc(thumb[i] >> 5 << 2, ofp);
275 putc(thumb[i] >> 11 << 3, ofp);
276 }
277 free(thumb);
278 }
279
jpeg_thumb()280 void LibRaw::jpeg_thumb()
281 {
282 char *thumb;
283
284 thumb = (char *)malloc(thumb_length);
285 merror(thumb, "jpeg_thumb()");
286 fread(thumb, 1, thumb_length, ifp);
287 jpeg_thumb_writer(ofp, thumb, thumb_length);
288 free(thumb);
289 }
290