/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 | 2.52k | { |
23 | 2.52k | int i, row, col; |
24 | 2.52k | double step; |
25 | 2.52k | float r, c, fr, fc; |
26 | 2.52k | unsigned ur, uc; |
27 | 2.52k | ushort wide, high, (*img)[4], (*pix)[4]; |
28 | | |
29 | 2.52k | if (!fuji_width) |
30 | 2.38k | return; |
31 | 138 | fuji_width = (fuji_width - 1 + shrink) >> shrink; |
32 | 138 | step = sqrt(0.5); |
33 | 138 | wide = ushort(fuji_width / step); |
34 | 138 | 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 | 138 | if (INT64(wide) * INT64(high) * INT64(sizeof(*img)) > |
38 | 138 | INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) |
39 | 0 | throw LIBRAW_EXCEPTION_TOOBIG; |
40 | | |
41 | 138 | img = (ushort(*)[4])calloc(high, wide * sizeof *img); |
42 | | |
43 | 138 | RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 0, 2); |
44 | | |
45 | 727k | for (row = 0; row < high; row++) |
46 | 50.0M | for (col = 0; col < wide; col++) |
47 | 49.3M | { |
48 | 49.3M | ur = unsigned( r = float(fuji_width + (row - col) * step)); |
49 | 49.3M | uc = unsigned( c = float( (row + col) * step)); |
50 | 49.3M | if (ur > (unsigned)height - 2 || uc > (unsigned)width - 2) |
51 | 47.4M | continue; |
52 | 1.81M | fr = r - ur; |
53 | 1.81M | fc = c - uc; |
54 | 1.81M | pix = image + ur * width + uc; |
55 | 3.80M | for (i = 0; i < colors; i++) |
56 | 1.98M | img[row * wide + col][i] = |
57 | 1.98M | ushort( |
58 | 1.98M | (pix[0][i] * (1 - fc) + pix[1][i] * fc) * (1 - fr) + |
59 | 1.98M | (pix[width][i] * (1 - fc) + pix[width + 1][i] * fc) * fr); |
60 | 1.81M | } |
61 | | |
62 | 138 | free(image); |
63 | 138 | width = wide; |
64 | 138 | height = high; |
65 | 138 | image = img; |
66 | 138 | fuji_width = 0; |
67 | 138 | RUN_CALLBACK(LIBRAW_PROGRESS_FUJI_ROTATE, 1, 2); |
68 | 138 | } |
69 | | |
70 | | void LibRaw::stretch() |
71 | 2.52k | { |
72 | 2.52k | ushort newdim, (*img)[4], *pix0, *pix1; |
73 | 2.52k | int row, col, c; |
74 | 2.52k | double rc, frac; |
75 | | |
76 | 2.52k | if (pixel_aspect == 1) |
77 | 2.47k | return; |
78 | 57 | RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH, 0, 2); |
79 | 57 | if (pixel_aspect < 1) |
80 | 28 | { |
81 | 28 | newdim = ushort(height / pixel_aspect + 0.5); |
82 | 28 | img = (ushort(*)[4])calloc(width, newdim * sizeof *img); |
83 | 11.0k | for (rc = row = 0; row < newdim; row++, rc += pixel_aspect) |
84 | 11.0k | { |
85 | 11.0k | frac = int(rc - double(c = int(rc))); |
86 | 11.0k | pix0 = pix1 = image[c * width]; |
87 | 11.0k | if (c + 1 < height) |
88 | 10.9k | pix1 += width * 4; |
89 | 3.40M | for (col = 0; col < width; col++, pix0 += 4, pix1 += 4) |
90 | 10.1M | FORCC img[row * width + col][c] = |
91 | 10.1M | ushort(pix0[c] * (1 - frac) + pix1[c] * frac + 0.5); |
92 | 11.0k | } |
93 | 28 | height = newdim; |
94 | 28 | } |
95 | 29 | else |
96 | 29 | { |
97 | 29 | newdim = ushort(width * pixel_aspect + 0.5); |
98 | 29 | img = (ushort(*)[4])calloc(height, newdim * sizeof *img); |
99 | 28.9k | for (rc = col = 0; col < newdim; col++, rc += 1 / pixel_aspect) |
100 | 28.8k | { |
101 | 28.8k | frac = int(rc - double(c = int(rc))); |
102 | 28.8k | pix0 = pix1 = image[c]; |
103 | 28.8k | if (c + 1 < width) |
104 | 28.8k | pix1 += 4; |
105 | 4.41M | for (row = 0; row < height; row++, pix0 += width * 4, pix1 += width * 4) |
106 | 13.1M | FORCC img[row * newdim + col][c] = |
107 | 13.1M | ushort(pix0[c] * (1 - frac) + pix1[c] * frac + 0.5); |
108 | 28.8k | } |
109 | 29 | width = newdim; |
110 | 29 | } |
111 | 57 | free(image); |
112 | 57 | image = img; |
113 | 57 | RUN_CALLBACK(LIBRAW_PROGRESS_STRETCH, 1, 2); |
114 | 57 | } |