/src/libraw/src/metadata/adobepano.cpp
Line | Count | Source |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2025 LibRaw LLC (info@libraw.org) |
3 | | * |
4 | | |
5 | | LibRaw is free software; you can redistribute it and/or modify |
6 | | it under the terms of the one of two licenses as you choose: |
7 | | |
8 | | 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
9 | | (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
10 | | |
11 | | 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
12 | | (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
13 | | |
14 | | */ |
15 | | |
16 | | #include "../../internal/dcraw_defs.h" |
17 | | |
18 | | void LibRaw::parseAdobePanoMakernote() |
19 | 11.3k | { |
20 | 11.3k | uchar *PrivateMknBuf; |
21 | 11.3k | unsigned posPrivateMknBuf; |
22 | 11.3k | unsigned PrivateMknLength; |
23 | 11.3k | unsigned PrivateOrder; |
24 | 11.3k | unsigned PrivateEntries, PrivateTagID, PrivateTagType, PrivateTagCount; |
25 | 11.3k | unsigned PrivateTagBytes; |
26 | 11.3k | int truncated; |
27 | | |
28 | 11.3k | #define CHECKSPACE(s) \ |
29 | 173k | if (posPrivateMknBuf + (s) > PrivateMknLength) \ |
30 | 173k | { \ |
31 | 1.63k | free(PrivateMknBuf); \ |
32 | 1.63k | return; \ |
33 | 1.63k | } |
34 | | |
35 | 11.3k | order = 0x4d4d; |
36 | 11.3k | truncated = 0; |
37 | 11.3k | PrivateMknLength = get4(); |
38 | | |
39 | 11.3k | if ((PrivateMknLength > 4) && (PrivateMknLength < 10240000) && |
40 | 3.78k | (PrivateMknBuf = (uchar *)calloc(PrivateMknLength + 1024,1))) |
41 | 3.78k | { // 1024b for safety |
42 | 3.78k | fread(PrivateMknBuf, PrivateMknLength, 1, ifp); |
43 | 3.78k | PrivateOrder = sget2(PrivateMknBuf); |
44 | 3.78k | PrivateEntries = sget2(PrivateMknBuf + 2); |
45 | 3.78k | if ((PrivateEntries > 1000) || |
46 | 3.56k | ((PrivateOrder != 0x4d4d) && (PrivateOrder != 0x4949))) |
47 | 465 | { |
48 | 465 | free(PrivateMknBuf); |
49 | 465 | return; |
50 | 465 | } |
51 | 3.32k | posPrivateMknBuf = 4; |
52 | 75.9k | while (PrivateEntries--) |
53 | 75.5k | { |
54 | 75.5k | order = 0x4d4d; |
55 | 75.5k | CHECKSPACE(8); |
56 | 74.8k | PrivateTagID = sget2(PrivateMknBuf + posPrivateMknBuf); |
57 | 74.8k | PrivateTagType = sget2(PrivateMknBuf + posPrivateMknBuf + 2); |
58 | 74.8k | PrivateTagCount = sget4(PrivateMknBuf + posPrivateMknBuf + 4); |
59 | 74.8k | posPrivateMknBuf += 8; |
60 | 74.8k | order = PrivateOrder; |
61 | | |
62 | 74.8k | if (truncated && !PrivateTagCount) |
63 | 3.22k | continue; |
64 | | |
65 | 71.6k | PrivateTagBytes = PrivateTagCount * |
66 | 71.6k | tagtype_dataunit_bytes[(PrivateTagType <= LIBRAW_EXIFTAG_TYPE_IFD8) ? PrivateTagType : 0]; |
67 | 71.6k | if(PrivateTagBytes > 10240000u) |
68 | 961 | { |
69 | 961 | free(PrivateMknBuf); |
70 | 961 | return; |
71 | 961 | } |
72 | 70.6k | if (PrivateTagID == 0x0002) |
73 | 1.36k | { |
74 | 1.36k | posPrivateMknBuf += 2; |
75 | 1.36k | CHECKSPACE(2); |
76 | 1.32k | if (sget2(PrivateMknBuf + posPrivateMknBuf)) |
77 | 453 | { |
78 | 453 | truncated = 1; |
79 | 453 | } |
80 | 876 | else |
81 | 876 | { |
82 | 876 | posPrivateMknBuf += 2; |
83 | 876 | } |
84 | 1.32k | } |
85 | 69.3k | else if (PrivateTagID == 0x0013) |
86 | 1.45k | { |
87 | 1.45k | ushort nWB, cnt, tWB; |
88 | 1.45k | CHECKSPACE(2); |
89 | 1.37k | nWB = sget2(PrivateMknBuf + posPrivateMknBuf); |
90 | 1.37k | posPrivateMknBuf += 2; |
91 | 1.37k | if (nWB > 0x100) |
92 | 249 | break; |
93 | 55.6k | for (cnt = 0; cnt < nWB; cnt++) |
94 | 55.0k | { |
95 | 55.0k | CHECKSPACE(2); |
96 | 54.8k | tWB = sget2(PrivateMknBuf + posPrivateMknBuf); |
97 | 54.8k | if (tWB < 0x100) |
98 | 19.5k | { |
99 | 19.5k | CHECKSPACE(4); |
100 | 19.2k | icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2); |
101 | 19.2k | icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 4); |
102 | 19.2k | icWBC[tWB][1] = icWBC[tWB][3] = 0x100; |
103 | 19.2k | } |
104 | 54.5k | posPrivateMknBuf += 6; |
105 | 54.5k | } |
106 | 1.12k | } |
107 | 67.8k | else if (PrivateTagID == 0x0027) |
108 | 862 | { |
109 | 862 | ushort nWB, cnt, tWB; |
110 | 862 | CHECKSPACE(2); |
111 | 813 | nWB = sget2(PrivateMknBuf + posPrivateMknBuf); |
112 | 813 | posPrivateMknBuf += 2; |
113 | 813 | if (nWB > 0x100) |
114 | 81 | break; |
115 | 13.5k | for (cnt = 0; cnt < nWB; cnt++) |
116 | 12.9k | { |
117 | 12.9k | CHECKSPACE(2); |
118 | 12.8k | tWB = sget2(PrivateMknBuf + posPrivateMknBuf); |
119 | 12.8k | if (tWB < 0x100) |
120 | 6.29k | { |
121 | 6.29k | CHECKSPACE(6); |
122 | 6.25k | icWBC[tWB][0] = sget2(PrivateMknBuf + posPrivateMknBuf + 2); |
123 | 6.25k | icWBC[tWB][1] = icWBC[tWB][3] = |
124 | 6.25k | sget2(PrivateMknBuf + posPrivateMknBuf + 4); |
125 | 6.25k | icWBC[tWB][2] = sget2(PrivateMknBuf + posPrivateMknBuf + 6); |
126 | 6.25k | } |
127 | 12.8k | posPrivateMknBuf += 8; |
128 | 12.8k | } |
129 | 732 | } |
130 | 66.9k | else if (PrivateTagID == 0x0121) |
131 | 153 | { |
132 | 153 | CHECKSPACE(4); |
133 | 69 | imPana.Multishot = sget4(PrivateMknBuf + posPrivateMknBuf); |
134 | 69 | posPrivateMknBuf += 4; |
135 | 69 | } |
136 | 66.8k | else |
137 | 66.8k | { |
138 | 66.8k | if (PrivateTagBytes > 4) |
139 | 1.70k | posPrivateMknBuf += PrivateTagBytes; |
140 | 65.1k | else if (!truncated) |
141 | 64.9k | posPrivateMknBuf += 4; |
142 | 151 | else |
143 | 151 | { |
144 | 151 | if (PrivateTagBytes <= 2) |
145 | 77 | posPrivateMknBuf += 2; |
146 | 74 | else |
147 | 74 | posPrivateMknBuf += 4; |
148 | 151 | } |
149 | 66.8k | } |
150 | 70.6k | } |
151 | 722 | free(PrivateMknBuf); |
152 | 722 | } |
153 | 11.3k | #undef CHECKSPACE |
154 | 11.3k | } |