* ptp-pack.c,config.c,ptp.c: Implemented EOS ImageSize and

* ImageFormat handling.


git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@12210 67ed7778-7388-44ab-90cf-0a291f65f57c
This commit is contained in:
Marcus Meissner
2009-07-10 16:57:43 +00:00
parent 5d9257080d
commit edc8a96edc
4 changed files with 210 additions and 44 deletions

View File

@@ -9,6 +9,7 @@
copyright, lensname, serialnr, shuttercount, availableshots
* ptp.c: decode EOS strings better
* ptp-pack.c: dpd.GetSet adjustments.
* ptp-pack.c,config.c,ptp.c: Implemented EOS ImageSize and ImageFormat handling.
2009-05-26 Marcus Meissner <marcus@jet.franken.de>

View File

@@ -1452,6 +1452,38 @@ static struct deviceproptableu16 canon_isospeed[] = {
};
GENERIC16TABLE(Canon_ISO,canon_isospeed)
/* see ptp-pack.c:ptp_unpack_EOS_ImageFormat */
static struct deviceproptableu16 canon_eos_image_format[] = {
{ N_("RAW"), 0x0400, 0 },
{ N_("sRAW1"), 0x1400, 0 },
{ N_("sRAW2"), 0x2400, 0 },
{ N_("L/Fine"), 0x0300, 0 },
{ N_("L/Normal"), 0x0200, 0 },
{ N_("M/Fine"), 0x1300, 0 },
{ N_("M/Normal"), 0x1200, 0 },
{ N_("S/Fine"), 0x2300, 0 },
{ N_("S/Normal"), 0x2200, 0 },
{ N_("RAW + L/Fine"), 0x0403, 0 },
{ N_("sRAW1 + L/Fine"), 0x1403, 0 },
{ N_("sRAW2 + L/Fine"), 0x2403, 0 },
{ N_("RAW + M/Fine"), 0x0413, 0 },
{ N_("sRAW1 + M/Fine"), 0x1413, 0 },
{ N_("sRAW2 + M/Fine"), 0x2413, 0 },
{ N_("RAW + S/Fine"), 0x0423, 0 },
{ N_("sRAW1 + S/Fine"), 0x1423, 0 },
{ N_("sRAW2 + S/Fine"), 0x2423, 0 },
{ N_("RAW + L/Normal"), 0x0402, 0 },
{ N_("sRAW1 + L/Normal"), 0x1402, 0 },
{ N_("sRAW2 + L/Normal"), 0x2402, 0 },
{ N_("RAW + M/Normal"), 0x0412, 0 },
{ N_("sRAW1 + M/Normal"), 0x1412, 0 },
{ N_("sRAW2 + M/Normal"), 0x2412, 0 },
{ N_("RAW + S/Normal"), 0x0422, 0 },
{ N_("sRAW1 + S/Normal"), 0x1422, 0 },
{ N_("sRAW2 + S/Normal"), 0x2422, 0 },
};
GENERIC16TABLE(Canon_EOS_ImageFormat,canon_eos_image_format)
static struct deviceproptableu16 canon_eos_aeb[] = {
{ N_("off"), 0x0000, 0 },
{ "+/- 1/3", 0x0003, 0 },
@@ -3294,7 +3326,8 @@ static struct submenu image_settings_menu[] = {
{ N_("Image Quality"), "imgquality", PTP_DPC_CompressionSetting, PTP_VENDOR_NIKON, PTP_DTC_UINT8, _get_Compression, _put_Compression},
{ N_("Canon Image Quality"), "canonimgquality", PTP_DPC_CANON_ImageQuality, PTP_VENDOR_CANON, PTP_DTC_UINT8, _get_Canon_Quality, _put_Canon_Quality},
{ N_("Canon Image Format"), "canonimgformat", PTP_DPC_CANON_FullViewFileFormat, PTP_VENDOR_CANON, PTP_DTC_UINT8, _get_Canon_Capture_Format, _put_Canon_Capture_Format},
{ N_("Image Size"), "imgsize", PTP_DPC_ImageSize, 0, PTP_DTC_STR, _get_ImageSize, _put_ImageSize},
{ N_("EOS Image Format"), "imgformat", PTP_DPC_CANON_EOS_ImageFormat, PTP_VENDOR_CANON, PTP_DTC_UINT16, _get_Canon_EOS_ImageFormat, _put_Canon_EOS_ImageFormat},
{ N_("Image Size"), "imgsize", PTP_DPC_ImageSize, 0, PTP_DTC_STR, _get_ImageSize, _put_ImageSize},
{ N_("Canon Image Size"), "canonimgsize", PTP_DPC_CANON_ImageSize, PTP_VENDOR_CANON, PTP_DTC_UINT8, _get_Canon_Size, _put_Canon_Size},
{ N_("ISO Speed"), "iso", PTP_DPC_CANON_ISOSpeed, PTP_VENDOR_CANON, PTP_DTC_UINT16, _get_Canon_ISO, _put_Canon_ISO},
{ N_("ISO Speed"), "iso", PTP_DPC_ExposureIndex, 0, PTP_DTC_UINT16, _get_ISO, _put_ISO},

View File

@@ -65,19 +65,19 @@ dtoh64p (PTPParams *params, uint64_t var)
}
static inline uint16_t
dtoh16ap (PTPParams *params, unsigned char *a)
dtoh16ap (PTPParams *params, const unsigned char *a)
{
return ((params->byteorder==PTP_DL_LE)?le16atoh(a):be16atoh(a));
}
static inline uint32_t
dtoh32ap (PTPParams *params, unsigned char *a)
dtoh32ap (PTPParams *params, const unsigned char *a)
{
return ((params->byteorder==PTP_DL_LE)?le32atoh(a):be32atoh(a));
}
static inline uint64_t
dtoh64ap (PTPParams *params, unsigned char *a)
dtoh64ap (PTPParams *params, const unsigned char *a)
{
return ((params->byteorder==PTP_DL_LE)?le64atoh(a):be64atoh(a));
}
@@ -1154,6 +1154,92 @@ ptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry
fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]);
}
static inline uint16_t
ptp_unpack_EOS_ImageFormat (PTPParams* params, unsigned char** data )
{
/*
EOS ImageFormat entries (of at least the 5DMII and the 400D ) look like this:
uint32: number of entries / generated files (1 or 2)
uint32: size of this entry in bytes (most likely allways 0x10)
uint32: image type (1 == JPG, 6 == RAW)
uint32: image size (0 == Large, 1 == Medium, 2 == Small)
uint32: image compression (2 == Standard/JPG, 3 == Fine/JPG, 4 == Lossles/RAW)
If number of entries is 2 the last uint32 repeat.
example:
0: 0x 1
1: 0x 10
2: 0x 6
3: 0x 1
4: 0x 4
The idea is to simply 'condense' these values to just one uint16 to be able to conveniontly
use the available enumeration facilities (look-up table). The image size and compression
values fully describe the image format. Hence we generate a uint16 with the four nibles set
as follows: entry 1 size | entry 1 compression | entry 2 size | entry 2 compression.
The above example would result in the value 0x1400.
*/
const unsigned char* d = *data;
uint32_t n = dtoh32a( d );
uint32_t l, s1, c1, s2 = 0, c2 = 0;
if (n != 1 && n !=2) {
ptp_debug (params, "parsing EOS ImageFormat property failed (n != 1 && n != 2: %d)", n);
return 0;
}
l = dtoh32a( d+=4 );
if (l != 0x10) {
ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l);
return 0;
}
d+=4; /* skip type */
s1 = dtoh32a( d+=4 );
c1 = dtoh32a( d+=4 );
if (n == 2) {
l = dtoh32a( d+=4 );
if (l != 0x10) {
ptp_debug (params, "parsing EOS ImageFormat property failed (l != 0x10: 0x%x)", l);
return 0;
}
d+=4; /* skip type */
s2 = dtoh32a( d+=4 );
c2 = dtoh32a( d+=4 );
}
*data = (unsigned char*) d+4;
return ((s1 & 0xF) << 12) | ((c1 & 0xF) << 8) | ((s2 & 0xF) << 4) | ((c2 & 0xF) << 0);
}
static inline uint32_t
ptp_pack_EOS_ImageFormat (PTPParams* params, unsigned char* data, uint16_t value)
{
uint32_t n = (value & 0xFF) ? 2 : 1;
uint32_t s = 4 + 0x10 * n;
if( !data )
return s;
htod32a(data+=0, n);
htod32a(data+=4, 0x10);
htod32a(data+=4, ((value >> 8) & 0xF) == 4 ? 6 : 1);
htod32a(data+=4, (value >> 12) & 0xF);
htod32a(data+=4, (value >> 8) & 0xF);
if (n==2) {
htod32a(data+=4, 0x10);
htod32a(data+=4, ((value >> 0) & 0xF) == 4 ? 6 : 1);
htod32a(data+=4, (value >> 4) & 0xF);
htod32a(data+=4, (value >> 0) & 0xF);
}
return s;
}
/*
PTP EOS Changes Entry unpack
*/
@@ -1255,22 +1341,38 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
ptp_debug (params, " %d: %02x", j, data[j]);
break;
}
if (propxcnt) {
ptp_debug (params, "event %d: propxtype is %x, prop is 0x%04x, data type is 0x%04x, propxcnt is %d.",
i, propxtype, proptype, dpd->DataType, propxcnt);
dpd->FormFlag = PTP_DPFF_Enumeration;
dpd->FORM.Enum.NumberOfValues = propxcnt;
dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*propxcnt);
if (! propxcnt)
break;
ptp_debug (params, "event %d: propxtype is %x, prop is 0x%04x, data type is 0x%04x, propxcnt is %d.",
i, propxtype, proptype, dpd->DataType, propxcnt);
dpd->FormFlag = PTP_DPFF_Enumeration;
dpd->FORM.Enum.NumberOfValues = propxcnt;
dpd->FORM.Enum.SupportedValue = malloc (sizeof (PTPPropertyValue)*propxcnt);
switch (proptype) {
case PTP_DPC_CANON_EOS_ImageFormat:
case PTP_DPC_CANON_EOS_ImageFormatCF:
case PTP_DPC_CANON_EOS_ImageFormatSD:
case PTP_DPC_CANON_EOS_ImageFormatExtHD:
/* special handling of ImageFormat properties */
for (j=0;j<propxcnt;j++) {
dpd->FORM.Enum.SupportedValue[j].u16 =
dtoh16( ptp_unpack_EOS_ImageFormat( params, &data ) );
ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, dpd->FORM.Enum.SupportedValue[j].u16);
}
break;
default:
/* 'normal' enumerated types */
switch (dpd->DataType) {
#define XX( TYPE, CONV )\
for (j=0;j<propxcnt;j++) { \
dpd->FORM.Enum.SupportedValue[j].TYPE = CONV(data); \
ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, CONV(data)); \
data += 4; /* might only be for propxtype 3 */ \
} \
break;
for (j=0;j<propxcnt;j++) { \
dpd->FORM.Enum.SupportedValue[j].TYPE = CONV(data); \
ptp_debug (params, "event %d: suppval[%d] of %x is 0x%x.", i, j, proptype, CONV(data)); \
data += 4; /* might only be for propxtype 3 */ \
} \
break;
case PTP_DTC_INT16: XX( i16, dtoh16a );
case PTP_DTC_UINT32: XX( u32, dtoh32a );
case PTP_DTC_UINT16: XX( u16, dtoh16a );
@@ -1498,6 +1600,20 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize,
/* debug is printed in switch above this one */
break;
}
/* ImageFormat special handling */
switch (proptype) {
case PTP_DPC_CANON_EOS_ImageFormat:
case PTP_DPC_CANON_EOS_ImageFormatCF:
case PTP_DPC_CANON_EOS_ImageFormatSD:
case PTP_DPC_CANON_EOS_ImageFormatExtHD:
dpd->DataType = PTP_DTC_UINT16;
dpd->FactoryDefaultValue.u16 = ptp_unpack_EOS_ImageFormat( params, &data );
dpd->CurrentValue.u16 = dpd->FactoryDefaultValue.u16;
ptp_debug (params,"event %d: currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u8);
break;
}
break;
}
case 0: /* end marker */

View File

@@ -2130,37 +2130,53 @@ ptp_canon_eos_setdevicepropvalue (PTPParams* params,
break;
if (params->nrofcanon_props == i)
return PTP_RC_Undefined;
if (datatype != PTP_DTC_STR) {
data = calloc(sizeof(uint32_t),3);
size = sizeof(uint32_t)*3;
} else {
size = strlen(value->str) + 1 + 8;
data = calloc(sizeof(char),size);
switch (propcode) {
case PTP_DPC_CANON_EOS_ImageFormat:
case PTP_DPC_CANON_EOS_ImageFormatCF:
case PTP_DPC_CANON_EOS_ImageFormatSD:
case PTP_DPC_CANON_EOS_ImageFormatExtHD:
/* special handling of ImageFormat properties */
size = 8 + ptp_pack_EOS_ImageFormat( params, NULL, value->u16 );
data = malloc( size );
params->canon_props[i].dpd.CurrentValue.u16 = value->u16;
ptp_pack_EOS_ImageFormat( params, data + 8, value->u16 );
break;
default:
if (datatype != PTP_DTC_STR) {
data = calloc(sizeof(uint32_t),3);
size = sizeof(uint32_t)*3;
} else {
size = strlen(value->str) + 1 + 8;
data = calloc(sizeof(char),size);
}
switch (datatype) {
case PTP_DTC_UINT8:
/*fprintf (stderr, "%x -> %d\n", propcode, value->u8);*/
htod8a(&data[8], value->u8);
params->canon_props[i].dpd.CurrentValue.u8 = value->u8;
break;
case PTP_DTC_UINT16:
/*fprintf (stderr, "%x -> %d\n", propcode, value->u16);*/
htod16a(&data[8], value->u16);
params->canon_props[i].dpd.CurrentValue.u16 = value->u16;
break;
case PTP_DTC_UINT32:
/*fprintf (stderr, "%x -> %d\n", propcode, value->u32);*/
htod32a(&data[8], value->u32);
params->canon_props[i].dpd.CurrentValue.u32 = value->u32;
break;
case PTP_DTC_STR:
strcpy((char*)data + 8, value->str);
free (params->canon_props[i].dpd.CurrentValue.str);
params->canon_props[i].dpd.CurrentValue.str = strdup(value->str);
break;
}
}
htod32a(&data[0], size);
htod32a(&data[4], propcode);
switch (datatype) {
case PTP_DTC_UINT8:
/*fprintf (stderr, "%x -> %d\n", propcode, value->u8);*/
htod8a(&data[8], value->u8);
params->canon_props[i].dpd.CurrentValue.u8 = value->u8;
break;
case PTP_DTC_UINT16:
/*fprintf (stderr, "%x -> %d\n", propcode, value->u16);*/
htod16a(&data[8], value->u16);
params->canon_props[i].dpd.CurrentValue.u16 = value->u16;
break;
case PTP_DTC_UINT32:
/*fprintf (stderr, "%x -> %d\n", propcode, value->u32);*/
htod32a(&data[8], value->u32);
params->canon_props[i].dpd.CurrentValue.u32 = value->u32;
break;
case PTP_DTC_STR:
strcpy((char*)data + 8, value->str);
free (params->canon_props[i].dpd.CurrentValue.str);
params->canon_props[i].dpd.CurrentValue.str = strdup(value->str);
break;
}
ret = ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &data, NULL);
free (data);
return ret;