File indexing completed on 2025-01-05 03:57:05

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::fuji_rotate()
0022 {
0023   int i, row, col;
0024   double step;
0025   float r, c, fr, fc;
0026   unsigned ur, uc;
0027   ushort wide, high, (*img)[4], (*pix)[4];
0028 
0029   if (!fuji_width)
0030     return;
0031   fuji_width = (fuji_width - 1 + shrink) >> shrink;
0032   step = sqrt(0.5);
0033   wide = fuji_width / step;
0034   high = (height - fuji_width) / step;
0035 
0036   // All real fuji/rotated images are small, so check against max_raw_memory_mb here is safe
0037   if (INT64(wide) * INT64(high) * INT64(sizeof(*img))    >
0038       INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024))
0039     throw LIBRAW_EXCEPTION_TOOBIG;
0040 
0041   img = (ushort(*)[4])calloc(high, wide * sizeof *img);
0042 
0043   RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 0, 2);
0044 
0045   for (row = 0; row < high; row++)
0046     for (col = 0; col < wide; col++)
0047     {
0048       ur = r = fuji_width + (row - col) * step;
0049       uc = c = (row + col) * step;
0050       if (ur > (unsigned)height - 2 || uc > (unsigned)width - 2)
0051         continue;
0052       fr = r - ur;
0053       fc = c - uc;
0054       pix = image + ur * width + uc;
0055       for (i = 0; i < colors; i++)
0056         img[row * wide + col][i] =
0057             (pix[0][i] * (1 - fc) + pix[1][i] * fc) * (1 - fr) +
0058             (pix[width][i] * (1 - fc) + pix[width + 1][i] * fc) * fr;
0059     }
0060 
0061   free(image);
0062   width = wide;
0063   height = high;
0064   image = img;
0065   fuji_width = 0;
0066   RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 1, 2);
0067 }
0068 
0069 void LibRaw::stretch()
0070 {
0071   ushort newdim, (*img)[4], *pix0, *pix1;
0072   int row, col, c;
0073   double rc, frac;
0074 
0075   if (pixel_aspect == 1)
0076     return;
0077   RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH, 0, 2);
0078   if (pixel_aspect < 1)
0079   {
0080     newdim = height / pixel_aspect + 0.5;
0081     img = (ushort(*)[4])calloc(width, newdim * sizeof *img);
0082     for (rc = row = 0; row < newdim; row++, rc += pixel_aspect)
0083     {
0084       frac = rc - (c = rc);
0085       pix0 = pix1 = image[c * width];
0086       if (c + 1 < height)
0087         pix1 += width * 4;
0088       for (col = 0; col < width; col++, pix0 += 4, pix1 += 4)
0089         FORCC img[row * width + col][c] =
0090             pix0[c] * (1 - frac) + pix1[c] * frac + 0.5;
0091     }
0092     height = newdim;
0093   }
0094   else
0095   {
0096     newdim = width * pixel_aspect + 0.5;
0097     img = (ushort(*)[4])calloc(height, newdim * sizeof *img);
0098     for (rc = col = 0; col < newdim; col++, rc += 1 / pixel_aspect)
0099     {
0100       frac = rc - (c = rc);
0101       pix0 = pix1 = image[c];
0102       if (c + 1 < width)
0103         pix1 += 4;
0104       for (row = 0; row < height; row++, pix0 += width * 4, pix1 += width * 4)
0105         FORCC img[row * newdim + col][c] =
0106             pix0[c] * (1 - frac) + pix1[c] * frac + 0.5;
0107     }
0108     width = newdim;
0109   }
0110   free(image);
0111   image = img;
0112   RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH, 1, 2);
0113 }