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(&timestamp);
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