Skip to content

Commit 601734e

Browse files
committed
ptp2: fix missing JPEG info for RAW+JPEG formats of 1DX and R5m2
This brings my original ptp_unpack_EOS_ImageFormat() documentation up-to-date with new M1/M2 and new 0/1 compression info added with 5Ds, 1DXm2 and R5m2. It also fixes the problem that led to a double entry of e.g. `RAW` in the imageformat config output visible in gphoto#1028 and also in the 1DX sample here: https://github.com/gphoto/libgphoto2/blob/5b7f7c168dd3e86f43b590a7456883e1dec11709/camlibs/ptp2/cameras/canon-eos-1dx.txt#L255-L269
1 parent c053bd7 commit 601734e

File tree

2 files changed

+75
-60
lines changed

2 files changed

+75
-60
lines changed

camlibs/ptp2/config.c

+18-18
Original file line numberDiff line numberDiff line change
@@ -2687,20 +2687,20 @@ GENERIC16TABLE(Canon_ISO,canon_isospeed)
26872687

26882688
/* see ptp-pack.c:ptp_unpack_EOS_ImageFormat */
26892689
static struct deviceproptableu16 canon_eos_image_format[] = {
2690-
{ N_("RAW"), 0x0c00, 0 },
2691-
{ N_("mRAW"), 0x1c00, 0 },
2692-
{ N_("sRAW"), 0x2c00, 0 },
2693-
{ N_("cRAW"), 0x0b00, 0 },
2694-
{ N_("Large Fine JPEG"), 0x0300, 0 },
2695-
{ N_("Large Normal JPEG"), 0x0200, 0 },
2696-
{ N_("Medium Fine JPEG"), 0x1300, 0 },
2697-
{ N_("Medium Normal JPEG"), 0x1200, 0 },
2698-
{ N_("Small Fine JPEG"), 0x2300, 0 },
2699-
{ N_("Small Normal JPEG"), 0x2200, 0 },
2700-
{ N_("Small Fine JPEG"), 0xd300, 0 },
2701-
{ N_("Small Normal JPEG"), 0xd200, 0 },
2702-
{ N_("Smaller JPEG"), 0xe300, 0 },
2703-
{ N_("Tiny JPEG"), 0xf300, 0 },
2690+
{ N_("RAW"), 0x0cff, 0 },
2691+
{ N_("mRAW"), 0x1cff, 0 },
2692+
{ N_("sRAW"), 0x2cff, 0 },
2693+
{ N_("cRAW"), 0x0bff, 0 },
2694+
{ N_("Large Fine JPEG"), 0x03ff, 0 },
2695+
{ N_("Large Normal JPEG"), 0x02ff, 0 },
2696+
{ N_("Medium Fine JPEG"), 0x13ff, 0 },
2697+
{ N_("Medium Normal JPEG"), 0x12ff, 0 },
2698+
{ N_("Small Fine JPEG"), 0x23ff, 0 },
2699+
{ N_("Small Normal JPEG"), 0x22ff, 0 },
2700+
{ N_("Small Fine JPEG"), 0xd3ff, 0 },
2701+
{ N_("Small Normal JPEG"), 0xd2ff, 0 },
2702+
{ N_("Smaller JPEG"), 0xe3ff, 0 },
2703+
{ N_("Tiny JPEG"), 0xf3ff, 0 },
27042704
{ N_("RAW + Large Fine JPEG"), 0x0c03, 0 },
27052705
{ N_("mRAW + Large Fine JPEG"), 0x1c03, 0 },
27062706
{ N_("sRAW + Large Fine JPEG"), 0x2c03, 0 },
@@ -2741,10 +2741,10 @@ static struct deviceproptableu16 canon_eos_image_format[] = {
27412741
/* There are more RAW + 'smallish' JPEG combinations for at least the 5DM3 possible.
27422742
Axel was simply to lazy to exercise the combinatorial explosion. :-/ */
27432743
/* 1DX series 0 compression options */
2744-
{ N_("Small"), 0x2100, 0 },
2745-
{ N_("Medium 1"), 0x5100, 0 },
2746-
{ N_("Medium 2"), 0x6100, 0 },
2747-
{ N_("Large"), 0x0100, 0 },
2744+
{ N_("Small"), 0x21ff, 0 },
2745+
{ N_("Medium 1"), 0x51ff, 0 },
2746+
{ N_("Medium 2"), 0x61ff, 0 },
2747+
{ N_("Large"), 0x01ff, 0 },
27482748
{ N_("Small + RAW"), 0x0c21, 0 },
27492749
{ N_("Medium 1 + RAW"), 0x0c51, 0 },
27502750
{ N_("Medium 2 + RAW"), 0x0c61, 0 },

camlibs/ptp2/ptp-pack.c

+57-42
Original file line numberDiff line numberDiff line change
@@ -1407,66 +1407,77 @@ static inline uint16_t
14071407
ptp_unpack_EOS_ImageFormat (PTPParams* params, const unsigned char** data )
14081408
{
14091409
/*
1410-
EOS ImageFormat entries (of at least the 5DM2 and the 400D) look like this:
1411-
uint32: number of entries / generated files (1 or 2)
1412-
uint32: size of this entry in bytes (most likely always 0x10)
1413-
uint32: image type (1 == JPG, 6 == RAW)
1414-
uint32: image size (0 == Large, 1 == Medium, 2 == Small, 0xe == S1, 0xf == S2, 0x10 == S3)
1415-
uint32: image compression (2 == Standard/JPG, 3 == Fine/JPG, 4 == Lossles/RAW)
1416-
If the number of entries is 2 the last 4 uint32 repeat.
1417-
1418-
example:
1419-
0: 0x 1
1420-
1: 0x 10
1421-
2: 0x 6
1422-
3: 0x 1
1423-
4: 0x 4
1410+
EOS ImageFormat entries look are a sequence of u32 values:
1411+
0: number of entries / generated files (1 or 2)
1412+
1: size of this entry in bytes (most likely always 0x10 = 4 x u32)
1413+
2: image type:
1414+
1 == JPG
1415+
6 == RAW
1416+
3: image size:
1417+
0 == L
1418+
1 == M
1419+
2 == S
1420+
5 == M1 (e.g. 5Ds)
1421+
6 == M2
1422+
e == S1 (e.g. 5Dm3)
1423+
f == S2
1424+
10 == S3
1425+
4: image compression:
1426+
0 == user: JPG (e.g. 1DX, R5m2)
1427+
1 == ???: JPG (e.g. 1DXm2, 1DXm3)
1428+
2 == coarse: JPG (all)
1429+
3 == fine: JPG/cRAW (all)
1430+
4 == lossless: RAW (all)
1431+
1432+
If the number of entries is 2 the values 1-4 repeat
1433+
1434+
example (cRAW + coarse S1 JPEG): 2 10 6 0 3 10 1 e 2
14241435
14251436
The idea is to simply 'condense' these values to just one uint16 to be able to conveniently
1426-
use the available enumeration facilities (look-up table). The image size and compression
1427-
values used to fully describe the image format, but at least since EOS M50 (with cRAW)
1428-
it is no longer true - we need to store RAW flag (8).
1429-
Hence we generate a uint16 with the four nibles set as follows:
1437+
use the available enumeration facilities (look-up table).
1438+
Hence we generate a u16 value with the four nibles set as follows:
14301439
1431-
entry 1 size | entry 1 compression & RAW flag | entry 2 size | entry 2 compression & RAW flag.
1440+
entry 1 size | entry 1 type + compression | entry 2 size | entry 2 type + compression.
14321441
1433-
The above example would result in the value 0x1400.
1442+
* The S3 value (0xf) would overflow the nible, hence we decrease all S1,S2,S3 values by 1.
1443+
* The to encode the type RAW, we set the 4th bit in the compression nible to 1 (|= 8).
1444+
* To distinguish an "empty" second entry from the "custom L JPEG", we set it to 0xff.
14341445
1435-
The EOS 5D Mark III (and possibly other high-end EOS as well) added the extra fancy S1, S2
1436-
and S3 JPEG options. S1 replaces the old Small. -1 the S1/S2/S3 to prevent the 0x10 overflow.
1437-
*/
1446+
The above example would result in the value 0x0bd2.
1447+
*/
14381448

1439-
const unsigned char* d = *data;
1440-
uint32_t n = dtoh32a( d );
1449+
const uint8_t* d = *data;
1450+
uint32_t offset = 0;
1451+
uint32_t n = dtoh32o (d, offset);
14411452
uint32_t l, t1, s1, c1, t2 = 0, s2 = 0, c2 = 0;
14421453

14431454
if (n != 1 && n !=2) {
14441455
ptp_debug (params, "parsing EOS ImageFormat property failed (n != 1 && n != 2: %d)", n);
14451456
return 0;
14461457
}
14471458

1448-
l = dtoh32a( d+=4 );
1459+
l = dtoh32o (d, offset);
14491460
if (l != 0x10) {
14501461
ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l);
14511462
return 0;
14521463
}
14531464

1454-
t1 = dtoh32a( d+=4 );
1455-
s1 = dtoh32a( d+=4 );
1456-
c1 = dtoh32a( d+=4 );
1465+
t1 = dtoh32o (d, offset);
1466+
s1 = dtoh32o (d, offset);
1467+
c1 = dtoh32o (d, offset);
14571468

14581469
if (n == 2) {
1459-
l = dtoh32a( d+=4 );
1470+
l = dtoh32o (d, offset);
14601471
if (l != 0x10) {
14611472
ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l);
14621473
return 0;
14631474
}
1464-
t2 = dtoh32a( d+=4 );
1465-
s2 = dtoh32a( d+=4 );
1466-
c2 = dtoh32a( d+=4 );
1475+
t2 = dtoh32o (d, offset);
1476+
s2 = dtoh32o (d, offset);
1477+
c2 = dtoh32o (d, offset);
14671478
}
14681479

1469-
*data = (unsigned char*) d+4;
1480+
*data += offset;
14701481

14711482
/* deal with S1/S2/S3 JPEG sizes, see above. */
14721483
if( s1 >= 0xe )
@@ -1478,31 +1489,35 @@ ptp_unpack_EOS_ImageFormat (PTPParams* params, const unsigned char** data )
14781489
c1 |= (t1 == 6) ? 8 : 0;
14791490
c2 |= (t2 == 6) ? 8 : 0;
14801491

1492+
if (s2 == 0 && c2 == 0)
1493+
s2 = c2 = 0xF;
1494+
14811495
return ((s1 & 0xF) << 12) | ((c1 & 0xF) << 8) | ((s2 & 0xF) << 4) | ((c2 & 0xF) << 0);
14821496
}
14831497

14841498
static inline uint32_t
14851499
ptp_pack_EOS_ImageFormat (PTPParams* params, unsigned char* data, uint16_t value)
14861500
{
1487-
uint32_t n = (value & 0xFF) ? 2 : 1;
1501+
uint32_t n = (value & 0xFF) == 0xFF ? 1 : 2;
14881502
uint32_t s = 4 + 0x10 * n;
14891503

14901504
if( !data )
14911505
return s;
14921506

1493-
#define PACK_5DM3_SMALL_JPEG_SIZE( X ) (X) >= 0xd ? (X)+1 : (X)
1507+
#define PACK_EOS_S123_JPEG_SIZE( X ) (X) >= 0xd ? (X)+1 : (X)
14941508

14951509
htod32a(data+=0, n);
1510+
14961511
htod32a(data+=4, 0x10);
1497-
htod32a(data+=4, (((value >> 8) & 0xF) >> 3) ? 6 : 1);
1498-
htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 12) & 0xF));
1499-
htod32a(data+=4, ((value >> 8) & 0xF) & ~8);
1512+
htod32a(data+=4, value & 0x0800 ? 6 : 1);
1513+
htod32a(data+=4, PACK_EOS_S123_JPEG_SIZE((value >> 12) & 0xF));
1514+
htod32a(data+=4, (value >> 8) & 0x7);
15001515

15011516
if (n==2) {
15021517
htod32a(data+=4, 0x10);
1503-
htod32a(data+=4, (((value >> 0) & 0xF) >> 3) ? 6 : 1);
1504-
htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 4) & 0xF));
1505-
htod32a(data+=4, ((value >> 0) & 0xF) & ~8);
1518+
htod32a(data+=4, value & 0x08 ? 6 : 1);
1519+
htod32a(data+=4, PACK_EOS_S123_JPEG_SIZE((value >> 4) & 0xF));
1520+
htod32a(data+=4, (value >> 0) & 0x7);
15061521
}
15071522

15081523
#undef PACK_5DM3_SMALL_JPEG_SIZE

0 commit comments

Comments
 (0)