Skip to content

Commit dbad0be

Browse files
qarkaicaclark
authored andcommitted
Simplify jpeg-parser a bit
Comment out unused members in MPOEntry and clarify FIXME. Replace pointers with references. Use explicit types for parameters in parse callbacks. Flatten jpeg_get_mpo_data().
1 parent f428cc6 commit dbad0be

File tree

2 files changed

+122
-124
lines changed

2 files changed

+122
-124
lines changed

src/jpeg-parser.cc

+110-112
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "jpeg-parser.h"
2323

2424
#include <cstring>
25+
#include <functional>
2526

2627

2728
gboolean is_jpeg_container(const guchar *data, guint size)
@@ -108,69 +109,65 @@ static guint32 tiff_byte_get_int32(const guchar *f, TiffByteOrder bo)
108109
return GUINT32_FROM_BE(align_buf); // NOLINT
109110
}
110111

111-
static gint tiff_directory_offset(const guchar *data, const guint len,
112-
guint *offset, TiffByteOrder *bo)
112+
static gboolean tiff_directory_offset(const guchar *data, const guint len,
113+
guint &offset, TiffByteOrder &bo)
113114
{
114115
if (len < 8) return FALSE;
115116

116117
if (memcmp(data, "II", 2) == 0)
117118
{
118-
*bo = TIFF_BYTE_ORDER_INTEL;
119+
bo = TIFF_BYTE_ORDER_INTEL;
119120
}
120121
else if (memcmp(data, "MM", 2) == 0)
121122
{
122-
*bo = TIFF_BYTE_ORDER_MOTOROLA;
123+
bo = TIFF_BYTE_ORDER_MOTOROLA;
123124
}
124125
else
125126
{
126127
return FALSE;
127128
}
128129

129-
if (tiff_byte_get_int16(data + 2, *bo) != 0x002A)
130+
if (tiff_byte_get_int16(data + 2, bo) != 0x002A)
130131
{
131132
return FALSE;
132133
}
133134

134-
*offset = tiff_byte_get_int32(data + 4, *bo);
135+
offset = tiff_byte_get_int32(data + 4, bo);
135136

136-
return (*offset < len);
137+
return offset < len;
137138
}
138139

139-
using FuncParseIFDEntry = gint (*)(const guchar *, guint, guint, TiffByteOrder, gpointer);
140-
140+
using FuncParseIFDEntry = std::function<gint(const guchar *, guint, TiffByteOrder)>;
141141

142142
static gint tiff_parse_IFD_table(const guchar *tiff, guint offset,
143143
guint size, TiffByteOrder bo,
144-
guint *next_offset,
145-
FuncParseIFDEntry parse_entry, gpointer data)
144+
const FuncParseIFDEntry &parse_entry,
145+
guint *next_offset = nullptr)
146146
{
147-
guint count;
148-
guint i;
149-
guint next;
150-
151-
152147
/* We should be able to read number of entries in IFD0) */
153148
if (size < offset + 2) return -1;
154149

155-
count = tiff_byte_get_int16(tiff + offset, bo);
150+
guint count = tiff_byte_get_int16(tiff + offset, bo);
156151
offset += 2;
157152
/* Entries and next IFD offset must be readable */
158153
if (size < offset + count * TIFF_TIFD_SIZE + 4) return -1;
159154

160-
for (i = 0; i < count; i++)
155+
for (guint i = 0; i < count; i++)
161156
{
162-
parse_entry(tiff, offset + (i * TIFF_TIFD_SIZE), size, bo, data);
157+
parse_entry(tiff, offset + (i * TIFF_TIFD_SIZE), bo);
163158
}
164159

165-
next = tiff_byte_get_int32(tiff + offset + (count * TIFF_TIFD_SIZE), bo);
166-
if (next_offset) *next_offset = next;
160+
if (next_offset)
161+
{
162+
*next_offset = tiff_byte_get_int32(tiff + offset + (count * TIFF_TIFD_SIZE), bo);
163+
}
167164

168165
return 0;
169166
}
170167

171168
static gint mpo_parse_Index_IFD_entry(const guchar *tiff, guint offset,
172-
guint size, TiffByteOrder bo,
173-
gpointer data)
169+
guint size, TiffByteOrder bo,
170+
MPOData &mpo)
174171
{
175172
guint tag;
176173
guint format;
@@ -179,8 +176,6 @@ static gint mpo_parse_Index_IFD_entry(const guchar *tiff, guint offset,
179176
guint data_offset;
180177
guint data_length;
181178

182-
auto mpo = static_cast<MPOData *>(data);
183-
184179
tag = tiff_byte_get_int16(tiff + offset + TIFF_TIFD_OFFSET_TAG, bo);
185180
format = tiff_byte_get_int16(tiff + offset + TIFF_TIFD_OFFSET_FORMAT, bo);
186181
count = tiff_byte_get_int32(tiff + offset + TIFF_TIFD_OFFSET_COUNT, bo);
@@ -189,68 +184,66 @@ static gint mpo_parse_Index_IFD_entry(const guchar *tiff, guint offset,
189184

190185
if (tag == 0xb000)
191186
{
192-
mpo->version = data_val;
193-
DEBUG_1(" mpo version %x", mpo->version);
187+
mpo.version = data_val;
188+
DEBUG_1(" mpo version %x", mpo.version);
194189
}
195190
else if (tag == 0xb001)
196191
{
197-
mpo->num_images = data_val;
198-
DEBUG_1(" num images %x", mpo->num_images);
192+
mpo.num_images = data_val;
193+
DEBUG_1(" num images %x", mpo.num_images);
199194
}
200195
else if (tag == 0xb002)
201196
{
202-
guint i;
203197
data_offset = data_val;
204198
data_length = count;
205199
if (size < data_offset || size < data_offset + data_length)
206200
{
207201
return -1;
208202
}
209-
if (count != mpo->num_images * 16)
203+
if (count != mpo.num_images * 16)
210204
{
211205
return -1;
212206
}
213207

214-
mpo->images = g_new0(MPOEntry, mpo->num_images);
208+
mpo.images = g_new0(MPOEntry, mpo.num_images);
215209

216-
for (i = 0; i < mpo->num_images; i++) {
210+
for (guint i = 0; i < mpo.num_images; i++)
211+
{
217212
guint image_attr = tiff_byte_get_int32(tiff + data_offset + (i * 16), bo);
218-
mpo->images[i].type_code = image_attr & 0xffffff;
219-
mpo->images[i].representative = !!(image_attr & 0x20000000);
220-
mpo->images[i].dependent_child = !!(image_attr & 0x40000000);
221-
mpo->images[i].dependent_parent = !!(image_attr & 0x80000000);
222-
mpo->images[i].length = tiff_byte_get_int32(tiff + data_offset + (i * 16) + 4, bo);
223-
mpo->images[i].offset = tiff_byte_get_int32(tiff + data_offset + (i * 16) + 8, bo);
224-
mpo->images[i].dep1 = tiff_byte_get_int16(tiff + data_offset + (i * 16) + 12, bo);
225-
mpo->images[i].dep2 = tiff_byte_get_int16(tiff + data_offset + (i * 16) + 14, bo);
213+
mpo.images[i].type_code = image_attr & 0xffffff;
214+
mpo.images[i].representative = !!(image_attr & 0x20000000);
215+
mpo.images[i].dependent_child = !!(image_attr & 0x40000000);
216+
mpo.images[i].dependent_parent = !!(image_attr & 0x80000000);
217+
mpo.images[i].length = tiff_byte_get_int32(tiff + data_offset + (i * 16) + 4, bo);
218+
mpo.images[i].offset = tiff_byte_get_int32(tiff + data_offset + (i * 16) + 8, bo);
219+
mpo.images[i].dep1 = tiff_byte_get_int16(tiff + data_offset + (i * 16) + 12, bo);
220+
mpo.images[i].dep2 = tiff_byte_get_int16(tiff + data_offset + (i * 16) + 14, bo);
226221

227222
if (i == 0)
228223
{
229-
mpo->images[i].offset = 0;
224+
mpo.images[i].offset = 0;
230225
}
231226
else
232227
{
233-
mpo->images[i].offset += mpo->mpo_offset;
228+
mpo.images[i].offset += mpo.mpo_offset;
234229
}
235230

236-
DEBUG_1(" image %x %x %x", image_attr, mpo->images[i].length, mpo->images[i].offset);
231+
DEBUG_1(" image %x %x %x", image_attr, mpo.images[i].length, mpo.images[i].offset);
237232
}
238233
}
239234

240235
return 0;
241236
}
242237

243238
static gint mpo_parse_Attributes_IFD_entry(const guchar *tiff, guint offset,
244-
guint, TiffByteOrder bo,
245-
gpointer data)
239+
TiffByteOrder bo,
240+
MPOEntry &mpe)
246241
{
247242
guint tag;
248243
guint format;
249244
guint count;
250245
guint data_val;
251246

252-
auto mpe = static_cast<MPOEntry *>(data);
253-
254247
tag = tiff_byte_get_int16(tiff + offset + TIFF_TIFD_OFFSET_TAG, bo);
255248
format = tiff_byte_get_int16(tiff + offset + TIFF_TIFD_OFFSET_FORMAT, bo);
256249
count = tiff_byte_get_int32(tiff + offset + TIFF_TIFD_OFFSET_COUNT, bo);
@@ -260,33 +253,34 @@ static gint mpo_parse_Attributes_IFD_entry(const guchar *tiff, guint offset,
260253
switch (tag)
261254
{
262255
case 0xb000:
263-
mpe->MPFVersion = data_val;
256+
mpe.MPFVersion = data_val;
264257
DEBUG_1(" mpo version %x", data_val);
265258
break;
266259
case 0xb101:
267-
mpe->MPIndividualNum = data_val;
268-
DEBUG_1(" Individual Image Number %x", mpe->MPIndividualNum);
260+
mpe.MPIndividualNum = data_val;
261+
DEBUG_1(" Individual Image Number %x", mpe.MPIndividualNum);
269262
break;
270263
case 0xb201:
271-
mpe->PanOrientation = data_val;
264+
mpe.PanOrientation = data_val;
272265
break;
273-
/**
274-
275-
@FIXME
276-
Panorama Scanning Orientation PanOrientation 45569 B201 LONG 1 \n
277-
Panorama Horizontal Overlap PanOverlap_H 45570 B202 RATIONAL 1 \n
278-
Panorama Vertical Overlap PanOverlap_V 45571 B203 RATIONAL 1 \n
279-
Base Viewpoint Number BaseViewpointNum 45572 B204 LONG 1 \n
280-
Convergence Angle ConvergenceAngle 45573 B205 SRATIONAL 1 \n
281-
Baseline Length BaselineLength 45574 B206 RATIONAL 1 \n
282-
Divergence Angle VerticalDivergence 45575 B207 SRATIONAL 1 \n
283-
Horizontal Axis Distance AxisDistance_X 45576 B208 SRATIONAL 1 \n
284-
Vertical Axis Distance AxisDistance_Y 45577 B209 SRATIONAL 1 \n
285-
Collimation Axis Distance AxisDistance_Z 45578 B20A SRATIONAL 1 \n
286-
Yaw Angle YawAngle 45579 B20B SRATIONAL 1 \n
287-
Pitch Angle PitchAngle 45580 B20C SRATIONAL 1 \n
288-
Roll Angle RollAngle 45581 B20D
289-
*/
266+
/**
267+
@FIXME See section 5.2.4. MP Attribute IFD of
268+
CIPA DC-007-Translation-2021 Multi-Picture Format
269+
https://www.cipa.jp/std/documents/download_e.html?CIPA_DC-007-2021_E
270+
Tag Name Field Name Tag ID (Dec/Hex) Type Count
271+
Panorama Horizontal Overlap PanOverlap_H 45570 B202 RATIONAL 1
272+
Panorama Vertical Overlap PanOverlap_V 45571 B203 RATIONAL 1
273+
Base Viewpoint Number BaseViewpointNum 45572 B204 LONG 1
274+
Convergence Angle ConvergenceAngle 45573 B205 SRATIONAL 1
275+
Baseline Length BaselineLength 45574 B206 RATIONAL 1
276+
Divergence Angle VerticalDivergence 45575 B207 SRATIONAL 1
277+
Horizontal Axis Distance AxisDistance_X 45576 B208 SRATIONAL 1
278+
Vertical Axis Distance AxisDistance_Y 45577 B209 SRATIONAL 1
279+
Collimation Axis Distance AxisDistance_Z 45578 B20A SRATIONAL 1
280+
Yaw Angle YawAngle 45579 B20B SRATIONAL 1
281+
Pitch Angle PitchAngle 45580 B20C SRATIONAL 1
282+
Roll Angle RollAngle 45581 B20D SRATIONAL 1
283+
*/
290284
default:
291285
break;
292286
}
@@ -298,66 +292,70 @@ MPOData *jpeg_get_mpo_data(const guchar *data, guint size)
298292
{
299293
guint seg_offset;
300294
guint seg_size;
301-
if (jpeg_segment_find(data, size, JPEG_MARKER_APP2, "MPF\x00", 4, &seg_offset, &seg_size) && seg_size >16)
302-
{
303-
guint offset;
304-
guint next_offset = 0;
305-
TiffByteOrder bo;
306-
MPOData *mpo;
307-
guint i;
295+
if (!jpeg_segment_find(data, size, JPEG_MARKER_APP2, "MPF\x00", 4, &seg_offset, &seg_size) || seg_size <= 16) return nullptr;
308296

309-
DEBUG_1("mpo signature found at %x", seg_offset);
310-
seg_offset += 4;
311-
seg_size -= 4;
297+
DEBUG_1("mpo signature found at %x", seg_offset);
298+
seg_offset += 4;
299+
seg_size -= 4;
312300

313-
if (!tiff_directory_offset(data + seg_offset, seg_size, &offset, &bo)) return nullptr;
301+
guint offset;
302+
TiffByteOrder bo;
303+
if (!tiff_directory_offset(data + seg_offset, seg_size, offset, bo)) return nullptr;
314304

315-
mpo = g_new0(MPOData, 1);
316-
mpo->mpo_offset = seg_offset;
305+
auto *mpo = g_new0(MPOData, 1);
306+
mpo->mpo_offset = seg_offset;
317307

318-
tiff_parse_IFD_table(data + seg_offset, offset , seg_size, bo, &next_offset, mpo_parse_Index_IFD_entry, mpo);
319-
if (!mpo->images) mpo->num_images = 0;
308+
guint next_offset = 0;
309+
const auto parse_mpo_data = [seg_size, mpo](const guchar *tiff, guint offset, TiffByteOrder bo)
310+
{
311+
return mpo_parse_Index_IFD_entry(tiff, offset, seg_size, bo, *mpo);
312+
};
313+
tiff_parse_IFD_table(data + seg_offset, offset, seg_size, bo, parse_mpo_data, &next_offset);
320314

315+
if (!mpo->images) mpo->num_images = 0;
321316

322-
for (i = 0; i < mpo->num_images; i++)
317+
for (guint i = 0; i < mpo->num_images; i++)
318+
{
319+
if (mpo->images[i].offset + mpo->images[i].length > size)
323320
{
324-
if (mpo->images[i].offset + mpo->images[i].length > size)
325-
{
326-
mpo->num_images = i;
327-
DEBUG_1("MPO file truncated to %u valid images, %u %u", i, mpo->images[i].offset + mpo->images[i].length, size);
328-
break;
329-
}
321+
mpo->num_images = i;
322+
DEBUG_1("MPO file truncated to %u valid images, %u %u", i, mpo->images[i].offset + mpo->images[i].length, size);
323+
break;
330324
}
325+
}
331326

332-
for (i = 0; i < mpo->num_images; i++)
327+
for (guint i = 0; i < mpo->num_images; i++)
328+
{
329+
if (i == 0)
333330
{
334-
if (i == 0)
331+
offset = next_offset;
332+
}
333+
else
334+
{
335+
if (!jpeg_segment_find(data + mpo->images[i].offset, mpo->images[i].length, JPEG_MARKER_APP2, "MPF\x00", 4, &seg_offset, &seg_size) || seg_size <=16)
335336
{
336-
offset = next_offset;
337+
DEBUG_1("MPO image %u: MPO signature not found", i);
338+
continue;
337339
}
338-
else
339-
{
340-
if (!jpeg_segment_find(data + mpo->images[i].offset, mpo->images[i].length, JPEG_MARKER_APP2, "MPF\x00", 4, &seg_offset, &seg_size) || seg_size <=16)
341-
{
342-
DEBUG_1("MPO image %u: MPO signature not found", i);
343-
continue;
344-
}
345-
346-
seg_offset += 4;
347-
seg_size -= 4;
348-
if (!tiff_directory_offset(data + mpo->images[i].offset + seg_offset, seg_size, &offset, &bo))
349-
{
350-
DEBUG_1("MPO image %u: invalid directory offset", i);
351-
continue;
352-
}
353340

341+
seg_offset += 4;
342+
seg_size -= 4;
343+
if (!tiff_directory_offset(data + mpo->images[i].offset + seg_offset, seg_size, offset, bo))
344+
{
345+
DEBUG_1("MPO image %u: invalid directory offset", i);
346+
continue;
354347
}
355-
tiff_parse_IFD_table(data + mpo->images[i].offset + seg_offset, offset , seg_size, bo, nullptr, mpo_parse_Attributes_IFD_entry, &mpo->images[i]);
348+
356349
}
357350

358-
return mpo;
351+
const auto parse_mpo_entry = [&mpe = mpo->images[i]](const guchar *tiff, guint offset, TiffByteOrder bo)
352+
{
353+
return mpo_parse_Attributes_IFD_entry(tiff, offset, bo, mpe);
354+
};
355+
tiff_parse_IFD_table(data + mpo->images[i].offset + seg_offset, offset, seg_size, bo, parse_mpo_entry);
359356
}
360-
return nullptr;
357+
358+
return mpo;
361359
}
362360

363361
void jpeg_mpo_data_free(MPOData *mpo)

src/jpeg-parser.h

+12-12
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,18 @@ struct MPOEntry {
6262
guint MPFVersion;
6363
guint MPIndividualNum;
6464
guint PanOrientation;
65-
double PanOverlap_H;
66-
double PanOverlap_V;
67-
guint BaseViewpointNum;
68-
double ConvergenceAngle;
69-
double BaselineLength;
70-
double VerticalDivergence;
71-
double AxisDistance_X;
72-
double AxisDistance_Y;
73-
double AxisDistance_Z;
74-
double YawAngle;
75-
double PitchAngle;
76-
double RollAngle;
65+
// double PanOverlap_H;
66+
// double PanOverlap_V;
67+
// guint BaseViewpointNum;
68+
// double ConvergenceAngle;
69+
// double BaselineLength;
70+
// double VerticalDivergence;
71+
// double AxisDistance_X;
72+
// double AxisDistance_Y;
73+
// double AxisDistance_Z;
74+
// double YawAngle;
75+
// double PitchAngle;
76+
// double RollAngle;
7777
};
7878

7979

0 commit comments

Comments
 (0)