File indexing completed on 2025-01-05 03:56:52

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 
0021 void LibRaw::vc5_dng_load_raw_placeholder()
0022 {
0023     // placeholder only, real decoding implemented in GPR SDK
0024     throw LIBRAW_EXCEPTION_DECODE_RAW;
0025 }
0026 
0027 void LibRaw::adobe_copy_pixel(unsigned row, unsigned col, ushort **rp)
0028 {
0029   int c;
0030 
0031   if (tiff_samples == 2 && shot_select)
0032     (*rp)++;
0033   if (raw_image)
0034   {
0035     if (row < raw_height && col < raw_width)
0036       RAW(row, col) = curve[**rp];
0037     *rp += tiff_samples;
0038   }
0039   else
0040   {
0041     if (row < raw_height && col < raw_width)
0042       FORC(int(tiff_samples))
0043     image[row * raw_width + col][c] = curve[(*rp)[c]];
0044     *rp += tiff_samples;
0045   }
0046   if (tiff_samples == 2 && shot_select)
0047     (*rp)--;
0048 }
0049 void LibRaw::lossless_dng_load_raw()
0050 {
0051   unsigned trow = 0, tcol = 0, jwide, jrow, jcol, row, col, i, j;
0052   INT64 save;
0053   struct jhead jh;
0054   ushort *rp;
0055 
0056   int ss = shot_select;
0057   shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss,0,(LIBRAW_IFD_MAXCOUNT*2-1))] & 0xff;
0058 
0059   while (trow < raw_height)
0060   {
0061     checkCancel();
0062     save = ftell(ifp);
0063     if (tile_length < INT_MAX)
0064       fseek(ifp, get4(), SEEK_SET);
0065     if (!ljpeg_start(&jh, 0))
0066       break;
0067     jwide = jh.wide;
0068     if (filters)
0069       jwide *= jh.clrs;
0070 
0071     if(filters && (tiff_samples == 2)) // Fuji Super CCD
0072         jwide /= 2;
0073     try
0074     {
0075       switch (jh.algo)
0076       {
0077       case 0xc1:
0078         jh.vpred[0] = 16384;
0079         getbits(-1);
0080         for (jrow = 0; jrow + 7 < (unsigned)jh.high; jrow += 8)
0081         {
0082           checkCancel();
0083           for (jcol = 0; jcol + 7 < (unsigned)jh.wide; jcol += 8)
0084           {
0085             ljpeg_idct(&jh);
0086             rp = jh.idct;
0087             row = trow + jcol / tile_width + jrow * 2;
0088             col = tcol + jcol % tile_width;
0089             for (i = 0; i < 16; i += 2)
0090               for (j = 0; j < 8; j++)
0091                 adobe_copy_pixel(row + i, col + j, &rp);
0092           }
0093         }
0094         break;
0095       case 0xc3:
0096         for (row = col = jrow = 0; jrow < (unsigned)jh.high; jrow++)
0097         {
0098           checkCancel();
0099           rp = ljpeg_row(jrow, &jh);
0100           if (tiff_samples == 1 && jh.clrs > 1 && jh.clrs * jwide == raw_width)
0101             for (jcol = 0; jcol < jwide * jh.clrs; jcol++)
0102             {
0103               adobe_copy_pixel(trow + row, tcol + col, &rp);
0104               if (++col >= tile_width || col >= raw_width)
0105                 row += 1 + (col = 0);
0106             }
0107           else
0108             for (jcol = 0; jcol < jwide; jcol++)
0109             {
0110               adobe_copy_pixel(trow + row, tcol + col, &rp);
0111               if (++col >= tile_width || col >= raw_width)
0112                 row += 1 + (col = 0);
0113             }
0114         }
0115       }
0116     }
0117     catch (...)
0118     {
0119       ljpeg_end(&jh);
0120       shot_select = ss;
0121       throw;
0122     }
0123     fseek(ifp, save + 4, SEEK_SET);
0124     if ((tcol += tile_width) >= raw_width)
0125       trow += tile_length + (tcol = 0);
0126     ljpeg_end(&jh);
0127   }
0128   shot_select = ss;
0129 }
0130 
0131 void LibRaw::packed_dng_load_raw()
0132 {
0133   ushort *pixel, *rp;
0134   unsigned row, col;
0135 
0136   if (tile_length < INT_MAX)
0137   {
0138       packed_tiled_dng_load_raw();
0139       return;
0140   }
0141 
0142   int ss = shot_select;
0143   shot_select = libraw_internal_data.unpacker_data.dng_frames[LIM(ss,0,(LIBRAW_IFD_MAXCOUNT*2-1))] & 0xff;
0144 
0145   pixel = (ushort *)calloc(raw_width, tiff_samples * sizeof *pixel);
0146   try
0147   {
0148     for (row = 0; row < raw_height; row++)
0149     {
0150       checkCancel();
0151       if (tiff_bps == 16)
0152         read_shorts(pixel, raw_width * tiff_samples);
0153       else
0154       {
0155         getbits(-1);
0156         for (col = 0; col < raw_width * tiff_samples; col++)
0157           pixel[col] = getbits(tiff_bps);
0158       }
0159       for (rp = pixel, col = 0; col < raw_width; col++)
0160         adobe_copy_pixel(row, col, &rp);
0161     }
0162   }
0163   catch (...)
0164   {
0165     free(pixel);
0166     shot_select = ss;
0167     throw;
0168   }
0169   free(pixel);
0170   shot_select = ss;
0171 }
0172 #ifdef NO_JPEG
0173 void LibRaw::lossy_dng_load_raw() {}
0174 #else
0175 
0176 static void jpegErrorExit_d(j_common_ptr /*cinfo*/)
0177 {
0178   throw LIBRAW_EXCEPTION_DECODE_JPEG;
0179 }
0180 
0181 void LibRaw::lossy_dng_load_raw()
0182 {
0183   if (!image)
0184     throw LIBRAW_EXCEPTION_IO_CORRUPT;
0185   struct jpeg_decompress_struct cinfo;
0186   JSAMPARRAY buf;
0187   JSAMPLE(*pixel)[3];
0188   unsigned sorder = order, ntags, opcode, deg, i, j, c;
0189   unsigned trow = 0, tcol = 0, row, col;
0190   INT64 save = data_offset - 4;
0191   ushort cur[3][256];
0192   double coeff[9], tot;
0193 
0194   if (meta_offset)
0195   {
0196     fseek(ifp, meta_offset, SEEK_SET);
0197     order = 0x4d4d;
0198     ntags = get4();
0199     while (ntags--)
0200     {
0201       opcode = get4();
0202       get4();
0203       get4();
0204       if (opcode != 8)
0205       {
0206         fseek(ifp, get4(), SEEK_CUR);
0207         continue;
0208       }
0209       fseek(ifp, 20, SEEK_CUR);
0210       if ((c = get4()) > 2)
0211         break;
0212       fseek(ifp, 12, SEEK_CUR);
0213       if ((deg = get4()) > 8)
0214         break;
0215       for (i = 0; i <= deg && i < 9; i++)
0216         coeff[i] = getreal(LIBRAW_EXIFTAG_TYPE_DOUBLE);
0217       for (i = 0; i < 256; i++)
0218       {
0219         for (tot = j = 0; j <= deg; j++)
0220           tot += coeff[j] * pow(i / 255.0, (int)j);
0221         cur[c][i] = (ushort)(tot * 0xffff);
0222       }
0223     }
0224     order = sorder;
0225   }
0226   else
0227   {
0228     gamma_curve(1 / 2.4, 12.92, 1, 255);
0229     FORC3 memcpy(cur[c], curve, sizeof cur[0]);
0230   }
0231 
0232   struct jpeg_error_mgr pub;
0233   cinfo.err = jpeg_std_error(&pub);
0234   pub.error_exit = jpegErrorExit_d;
0235 
0236   jpeg_create_decompress(&cinfo);
0237 
0238   while (trow < raw_height)
0239   {
0240     fseek(ifp, save += 4, SEEK_SET);
0241     if (tile_length < INT_MAX)
0242       fseek(ifp, get4(), SEEK_SET);
0243     if (libraw_internal_data.internal_data.input->jpeg_src(&cinfo) == -1)
0244     {
0245       jpeg_destroy_decompress(&cinfo);
0246       throw LIBRAW_EXCEPTION_DECODE_JPEG;
0247     }
0248     jpeg_read_header(&cinfo, TRUE);
0249     jpeg_start_decompress(&cinfo);
0250     buf = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE,
0251                                      cinfo.output_width * 3, 1);
0252     try
0253     {
0254       while (cinfo.output_scanline < cinfo.output_height &&
0255              (row = trow + cinfo.output_scanline) < height)
0256       {
0257         checkCancel();
0258         jpeg_read_scanlines(&cinfo, buf, 1);
0259         pixel = (JSAMPLE(*)[3])buf[0];
0260         for (col = 0; col < cinfo.output_width && tcol + col < width; col++)
0261         {
0262           FORC3 image[row * width + tcol + col][c] = cur[c][pixel[col][c]];
0263         }
0264       }
0265     }
0266     catch (...)
0267     {
0268       jpeg_destroy_decompress(&cinfo);
0269       throw;
0270     }
0271     jpeg_abort_decompress(&cinfo);
0272     if ((tcol += tile_width) >= raw_width)
0273       trow += tile_length + (tcol = 0);
0274   }
0275   jpeg_destroy_decompress(&cinfo);
0276   maximum = 0xffff;
0277 }
0278 #endif