1 /* -*- C++ -*-
2  * Copyright 2019-2021 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 
vc5_dng_load_raw_placeholder()21 void LibRaw::vc5_dng_load_raw_placeholder()
22 {
23     // placeholder only, real decoding implemented in GPR SDK
24     throw LIBRAW_EXCEPTION_DECODE_RAW;
25 }
26 
adobe_copy_pixel(unsigned row,unsigned col,ushort ** rp)27 void LibRaw::adobe_copy_pixel(unsigned row, unsigned col, ushort **rp)
28 {
29   int c;
30 
31   if (tiff_samples == 2 && shot_select)
32     (*rp)++;
33   if (raw_image)
34   {
35     if (row < raw_height && col < raw_width)
36       RAW(row, col) = curve[**rp];
37     *rp += tiff_samples;
38   }
39   else
40   {
41     if (row < raw_height && col < raw_width)
42       FORC(int(tiff_samples))
43     image[row * raw_width + col][c] = curve[(*rp)[c]];
44     *rp += tiff_samples;
45   }
46   if (tiff_samples == 2 && shot_select)
47     (*rp)--;
48 }
lossless_dng_load_raw()49 void LibRaw::lossless_dng_load_raw()
50 {
51   unsigned trow = 0, tcol = 0, jwide, jrow, jcol, row, col, i, j;
52   INT64 save;
53   struct jhead jh;
54   ushort *rp;
55 
56   int ss = shot_select;
57   shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss,0,(LIBRAW_IFD_MAXCOUNT*2-1))] & 0xff;
58 
59   while (trow < raw_height)
60   {
61     checkCancel();
62     save = ftell(ifp);
63     if (tile_length < INT_MAX)
64       fseek(ifp, get4(), SEEK_SET);
65     if (!ljpeg_start(&jh, 0))
66       break;
67     jwide = jh.wide;
68     if (filters)
69       jwide *= jh.clrs;
70 
71     if(filters && (tiff_samples == 2)) // Fuji Super CCD
72         jwide /= 2;
73     try
74     {
75       switch (jh.algo)
76       {
77       case 0xc1:
78         jh.vpred[0] = 16384;
79         getbits(-1);
80         for (jrow = 0; jrow + 7 < (unsigned)jh.high; jrow += 8)
81         {
82           checkCancel();
83           for (jcol = 0; jcol + 7 < (unsigned)jh.wide; jcol += 8)
84           {
85             ljpeg_idct(&jh);
86             rp = jh.idct;
87             row = trow + jcol / tile_width + jrow * 2;
88             col = tcol + jcol % tile_width;
89             for (i = 0; i < 16; i += 2)
90               for (j = 0; j < 8; j++)
91                 adobe_copy_pixel(row + i, col + j, &rp);
92           }
93         }
94         break;
95       case 0xc3:
96         for (row = col = jrow = 0; jrow < (unsigned)jh.high; jrow++)
97         {
98           checkCancel();
99           rp = ljpeg_row(jrow, &jh);
100           if (tiff_samples == 1 && jh.clrs > 1 && jh.clrs * jwide == raw_width)
101             for (jcol = 0; jcol < jwide * jh.clrs; jcol++)
102             {
103               adobe_copy_pixel(trow + row, tcol + col, &rp);
104               if (++col >= tile_width || col >= raw_width)
105                 row += 1 + (col = 0);
106             }
107           else
108             for (jcol = 0; jcol < jwide; jcol++)
109             {
110               adobe_copy_pixel(trow + row, tcol + col, &rp);
111               if (++col >= tile_width || col >= raw_width)
112                 row += 1 + (col = 0);
113             }
114         }
115       }
116     }
117     catch (...)
118     {
119       ljpeg_end(&jh);
120       shot_select = ss;
121       throw;
122     }
123     fseek(ifp, save + 4, SEEK_SET);
124     if ((tcol += tile_width) >= raw_width)
125       trow += tile_length + (tcol = 0);
126     ljpeg_end(&jh);
127   }
128   shot_select = ss;
129 }
130 
packed_dng_load_raw()131 void LibRaw::packed_dng_load_raw()
132 {
133   ushort *pixel, *rp;
134   unsigned row, col;
135 
136   int ss = shot_select;
137   shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss,0,(LIBRAW_IFD_MAXCOUNT*2-1))] & 0xff;
138 
139   pixel = (ushort *)calloc(raw_width, tiff_samples * sizeof *pixel);
140   merror(pixel, "packed_dng_load_raw()");
141   try
142   {
143     for (row = 0; row < raw_height; row++)
144     {
145       checkCancel();
146       if (tiff_bps == 16)
147         read_shorts(pixel, raw_width * tiff_samples);
148       else
149       {
150         getbits(-1);
151         for (col = 0; col < raw_width * tiff_samples; col++)
152           pixel[col] = getbits(tiff_bps);
153       }
154       for (rp = pixel, col = 0; col < raw_width; col++)
155         adobe_copy_pixel(row, col, &rp);
156     }
157   }
158   catch (...)
159   {
160     free(pixel);
161     shot_select = ss;
162     throw;
163   }
164   free(pixel);
165   shot_select = ss;
166 }
167 #ifdef NO_JPEG
lossy_dng_load_raw()168 void LibRaw::lossy_dng_load_raw() {}
169 #else
170 
jpegErrorExit_d(j_common_ptr cinfo)171 static void jpegErrorExit_d(j_common_ptr cinfo)
172 {
173   throw LIBRAW_EXCEPTION_DECODE_JPEG;
174 }
175 
lossy_dng_load_raw()176 void LibRaw::lossy_dng_load_raw()
177 {
178   if (!image)
179     throw LIBRAW_EXCEPTION_IO_CORRUPT;
180   struct jpeg_decompress_struct cinfo;
181   JSAMPARRAY buf;
182   JSAMPLE(*pixel)[3];
183   unsigned sorder = order, ntags, opcode, deg, i, j, c;
184   unsigned trow = 0, tcol = 0, row, col;
185   INT64 save = data_offset - 4;
186   ushort cur[3][256];
187   double coeff[9], tot;
188 
189   if (meta_offset)
190   {
191     fseek(ifp, meta_offset, SEEK_SET);
192     order = 0x4d4d;
193     ntags = get4();
194     while (ntags--)
195     {
196       opcode = get4();
197       get4();
198       get4();
199       if (opcode != 8)
200       {
201         fseek(ifp, get4(), SEEK_CUR);
202         continue;
203       }
204       fseek(ifp, 20, SEEK_CUR);
205       if ((c = get4()) > 2)
206         break;
207       fseek(ifp, 12, SEEK_CUR);
208       if ((deg = get4()) > 8)
209         break;
210       for (i = 0; i <= deg && i < 9; i++)
211         coeff[i] = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE);
212       for (i = 0; i < 256; i++)
213       {
214         for (tot = j = 0; j <= deg; j++)
215           tot += coeff[j] * pow(i / 255.0, (int)j);
216         cur[c][i] = (ushort)(tot * 0xffff);
217       }
218     }
219     order = sorder;
220   }
221   else
222   {
223     gamma_curve(1 / 2.4, 12.92, 1, 255);
224     FORC3 memcpy(cur[c], curve, sizeof cur[0]);
225   }
226 
227   struct jpeg_error_mgr pub;
228   cinfo.err = jpeg_std_error(&pub);
229   pub.error_exit = jpegErrorExit_d;
230 
231   jpeg_create_decompress(&cinfo);
232 
233   while (trow < raw_height)
234   {
235     fseek(ifp, save += 4, SEEK_SET);
236     if (tile_length < INT_MAX)
237       fseek(ifp, get4(), SEEK_SET);
238     if (libraw_internal_data.internal_data.input->jpeg_src(&cinfo) == -1)
239     {
240       jpeg_destroy_decompress(&cinfo);
241       throw LIBRAW_EXCEPTION_DECODE_JPEG;
242     }
243     jpeg_read_header(&cinfo, TRUE);
244     jpeg_start_decompress(&cinfo);
245     buf = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE,
246                                      cinfo.output_width * 3, 1);
247     try
248     {
249       while (cinfo.output_scanline < cinfo.output_height &&
250              (row = trow + cinfo.output_scanline) < height)
251       {
252         checkCancel();
253         jpeg_read_scanlines(&cinfo, buf, 1);
254         pixel = (JSAMPLE(*)[3])buf[0];
255         for (col = 0; col < cinfo.output_width && tcol + col < width; col++)
256         {
257           FORC3 image[row * width + tcol + col][c] = cur[c][pixel[col][c]];
258         }
259       }
260     }
261     catch (...)
262     {
263       jpeg_destroy_decompress(&cinfo);
264       throw;
265     }
266     jpeg_abort_decompress(&cinfo);
267     if ((tcol += tile_width) >= raw_width)
268       trow += tile_length + (tcol = 0);
269   }
270   jpeg_destroy_decompress(&cinfo);
271   maximum = 0xffff;
272 }
273 #endif
274