/src/libraw/src/postprocessing/aspect_ratio.cpp
Line | Count | Source |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2025 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 | | |
21 | | void LibRaw::fuji_rotate() |
22 | 1.92k | { |
23 | 1.92k | int i, row, col; |
24 | 1.92k | double step; |
25 | 1.92k | float r, c, fr, fc; |
26 | 1.92k | unsigned ur, uc; |
27 | 1.92k | ushort wide, high, (*img)[4], (*pix)[4]; |
28 | | |
29 | 1.92k | if (!fuji_width) |
30 | 1.84k | return; |
31 | 82 | fuji_width = (fuji_width - 1 + shrink) >> shrink; |
32 | 82 | step = sqrt(0.5); |
33 | 82 | wide = ushort(fuji_width / step); |
34 | 82 | high = ushort((height - fuji_width) / step); |
35 | | |
36 | | // All real fuji/rotated images are small, so check against max_raw_memory_mb here is safe |
37 | 82 | if (INT64(wide) * INT64(high) * INT64(sizeof(*img)) > |
38 | 82 | INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
39 | 0 | throw LIBRAW_EXCEPTION_TOOBIG; |
40 | | |
41 | 82 | img = (ushort(*)[4])calloc(high, wide * sizeof *img); |
42 | | |
43 | 82 | RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 0, 2); |
44 | | |
45 | 534k | for (row = 0; row < high; row++) |
46 | 36.5M | for (col = 0; col < wide; col++) |
47 | 36.0M | { |
48 | 36.0M | ur = unsigned( r = float(fuji_width + (row - col) * step)); |
49 | 36.0M | uc = unsigned( c = float( (row + col) * step)); |
50 | 36.0M | if (ur > (unsigned)height - 2 || uc > (unsigned)width - 2) |
51 | 32.8M | continue; |
52 | 3.22M | fr = r - ur; |
53 | 3.22M | fc = c - uc; |
54 | 3.22M | pix = image + ur * width + uc; |
55 | 6.54M | for (i = 0; i < colors; i++) |
56 | 3.32M | img[row * wide + col][i] = |
57 | 3.32M | ushort( |
58 | 3.32M | (pix[0][i] * (1 - fc) + pix[1][i] * fc) * (1 - fr) + |
59 | 3.32M | (pix[width][i] * (1 - fc) + pix[width + 1][i] * fc) * fr); |
60 | 3.22M | } |
61 | | |
62 | 82 | free(image); |
63 | 82 | width = wide; |
64 | 82 | height = high; |
65 | 82 | image = img; |
66 | 82 | fuji_width = 0; |
67 | 82 | RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 1, 2); |
68 | 82 | } |
69 | | |
70 | | void LibRaw::stretch() |
71 | 1.92k | { |
72 | 1.92k | ushort newdim, (*img)[4], *pix0, *pix1; |
73 | 1.92k | int row, col, c; |
74 | 1.92k | double rc, frac; |
75 | | |
76 | 1.92k | if (pixel_aspect == 1) |
77 | 1.87k | return; |
78 | 48 | RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH, 0, 2); |
79 | 48 | if (pixel_aspect < 1) |
80 | 25 | { |
81 | 25 | newdim = ushort(height / pixel_aspect + 0.5); |
82 | 25 | img = (ushort(*)[4])calloc(width, newdim * sizeof *img); |
83 | 13.8k | for (rc = row = 0; row < newdim; row++, rc += pixel_aspect) |
84 | 13.7k | { |
85 | 13.7k | frac = int(rc - double(c = int(rc))); |
86 | 13.7k | pix0 = pix1 = image[c * width]; |
87 | 13.7k | if (c + 1 < height) |
88 | 13.6k | pix1 += width * 4; |
89 | 4.84M | for (col = 0; col < width; col++, pix0 += 4, pix1 += 4) |
90 | 14.5M | FORCC img[row * width + col][c] = |
91 | 14.5M | ushort(pix0[c] * (1 - frac) + pix1[c] * frac + 0.5); |
92 | 13.7k | } |
93 | 25 | height = newdim; |
94 | 25 | } |
95 | 23 | else |
96 | 23 | { |
97 | 23 | newdim = ushort(width * pixel_aspect + 0.5); |
98 | 23 | img = (ushort(*)[4])calloc(height, newdim * sizeof *img); |
99 | 30.5k | for (rc = col = 0; col < newdim; col++, rc += 1 / pixel_aspect) |
100 | 30.4k | { |
101 | 30.4k | frac = int(rc - double(c = int(rc))); |
102 | 30.4k | pix0 = pix1 = image[c]; |
103 | 30.4k | if (c + 1 < width) |
104 | 30.4k | pix1 += 4; |
105 | 5.36M | for (row = 0; row < height; row++, pix0 += width * 4, pix1 += width * 4) |
106 | 16.0M | FORCC img[row * newdim + col][c] = |
107 | 16.0M | ushort(pix0[c] * (1 - frac) + pix1[c] * frac + 0.5); |
108 | 30.4k | } |
109 | 23 | width = newdim; |
110 | 23 | } |
111 | 48 | free(image); |
112 | 48 | image = img; |
113 | 48 | RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH, 1, 2); |
114 | 48 | } |