~ubuntu-branches/debian/experimental/libmtp/experimental

« back to all changes in this revision

Viewing changes to src/ptp-pack.c

  • Committer: Package Import Robot
  • Author(s): Alessio Treglia
  • Date: 2012-06-16 10:39:41 UTC
  • mfrom: (0.2.7) (16.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120616103941-u61e72y10244eo9e
Tags: 1.1.3-24-g9aca343-1
* New upstream snapshot 1.1.3-24-g9aca343.
* Replace dh-autotools_dev with dh-autoreconf.
  - Build-Depends on dh-autoreconf, gnulib.
  - Install config.rpath by hand.
* Drop {1001-kfreebsd_hurd_ftbfs,1002-fix_libusb_checks}.patch,
  applied upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
473
473
        uint8_t filenamelen;
474
474
        uint8_t capturedatelen=0;
475
475
        /* let's allocate some memory first; correct assuming zero length dates */
476
 
        oidata=malloc(PTP_oi_MaxLen);
 
476
        oidata=malloc(PTP_oi_MaxLen + params->ocs64*4);
 
477
        *oidataptr=oidata;
477
478
        /* the caller should free it after use! */
478
479
#if 0
479
480
        char *capture_date="20020101T010101"; /* XXX Fake date */
480
481
#endif
481
 
        memset (oidata, 0, PTP_oi_MaxLen);
 
482
        memset (oidata, 0, PTP_oi_MaxLen + params->ocs64*4);
482
483
        htod32a(&oidata[PTP_oi_StorageID],oi->StorageID);
483
484
        htod16a(&oidata[PTP_oi_ObjectFormat],oi->ObjectFormat);
484
485
        htod16a(&oidata[PTP_oi_ProtectionStatus],oi->ProtectionStatus);
485
486
        htod32a(&oidata[PTP_oi_ObjectCompressedSize],oi->ObjectCompressedSize);
 
487
        if (params->ocs64)
 
488
                oidata += 4;
486
489
        htod16a(&oidata[PTP_oi_ThumbFormat],oi->ThumbFormat);
487
490
        htod32a(&oidata[PTP_oi_ThumbCompressedSize],oi->ThumbCompressedSize);
488
491
        htod32a(&oidata[PTP_oi_ThumbPixWidth],oi->ThumbPixWidth);
523
526
        }
524
527
#endif
525
528
        /* XXX this function should return dataset length */
526
 
        
527
 
        *oidataptr=oidata;
528
 
        return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3);
 
529
        return (PTP_oi_Filename+filenamelen*2+(capturedatelen+1)*3)+params->ocs64*4;
529
530
}
530
531
 
531
532
static time_t
582
583
        oi->ObjectFormat=dtoh16a(&data[PTP_oi_ObjectFormat]);
583
584
        oi->ProtectionStatus=dtoh16a(&data[PTP_oi_ProtectionStatus]);
584
585
        oi->ObjectCompressedSize=dtoh32a(&data[PTP_oi_ObjectCompressedSize]);
 
586
 
 
587
        /* Stupid Samsung Galaxy developers emit a 64bit objectcompressedsize */
 
588
        if ((data[PTP_oi_filenamelen] == 0) && (data[PTP_oi_filenamelen+4] != 0)) {
 
589
                params->ocs64 = 1;
 
590
                data += 4;
 
591
        }
585
592
        oi->ThumbFormat=dtoh16a(&data[PTP_oi_ThumbFormat]);
586
593
        oi->ThumbCompressedSize=dtoh32a(&data[PTP_oi_ThumbCompressedSize]);
587
594
        oi->ThumbPixWidth=dtoh32a(&data[PTP_oi_ThumbPixWidth]);
593
600
        oi->AssociationType=dtoh16a(&data[PTP_oi_AssociationType]);
594
601
        oi->AssociationDesc=dtoh32a(&data[PTP_oi_AssociationDesc]);
595
602
        oi->SequenceNumber=dtoh32a(&data[PTP_oi_SequenceNumber]);
 
603
 
596
604
        oi->Filename= ptp_unpack_string(params, data, PTP_oi_filenamelen, &filenamelen);
597
605
 
598
606
        capture_date = ptp_unpack_string(params, data,
1244
1252
ptp_unpack_EOS_ImageFormat (PTPParams* params, unsigned char** data )
1245
1253
{
1246
1254
        /*
1247
 
          EOS ImageFormat entries (of at least the 5DMII and the 400D ) look like this:
 
1255
          EOS ImageFormat entries (of at least the 5DM2 and the 400D) look like this:
1248
1256
                uint32: number of entries / generated files (1 or 2)
1249
1257
                uint32: size of this entry in bytes (most likely allways 0x10)
1250
1258
                uint32: image type (1 == JPG, 6 == RAW)
1251
 
                uint32: image size (0 == Large, 1 == Medium, 2 == Small)
 
1259
                uint32: image size (0 == Large, 1 == Medium, 2 == Small, 0xe == S1, 0xf == S2, 0x10 == S3)
1252
1260
                uint32: image compression (2 == Standard/JPG, 3 == Fine/JPG, 4 == Lossles/RAW)
1253
 
          If number of entries is 2 the last uint32 repeat.
 
1261
          If the number of entries is 2 the last 4 uint32 repeat.
1254
1262
 
1255
1263
          example:
1256
1264
                0: 0x       1
1259
1267
                3: 0x       1
1260
1268
                4: 0x       4
1261
1269
 
1262
 
          The idea is to simply 'condense' these values to just one uint16 to be able to conveniontly
 
1270
          The idea is to simply 'condense' these values to just one uint16 to be able to conveniently
1263
1271
          use the available enumeration facilities (look-up table). The image size and compression
1264
1272
          values fully describe the image format. Hence we generate a uint16 with the four nibles set
1265
1273
          as follows: entry 1 size | entry 1 compression | entry 2 size | entry 2 compression.
1266
1274
          The above example would result in the value 0x1400.
 
1275
 
 
1276
          The EOS 5D Mark III (and possibly other high-end EOS as well) added the extra fancy S1, S2
 
1277
          and S3 JPEG options. S1 replaces the old Small. -1 the S1/S2/S3 to prevent the 0x10 overflow.
1267
1278
          */
1268
1279
 
1269
1280
        const unsigned char* d = *data;
1298
1309
 
1299
1310
        *data = (unsigned char*) d+4;
1300
1311
 
 
1312
        /* deal with S1/S2/S3 JPEG sizes, see above. */
 
1313
        if( s1 >= 0xe )
 
1314
                s1--;
 
1315
        if( s2 >= 0xe )
 
1316
                s2--;
 
1317
 
1301
1318
        return ((s1 & 0xF) << 12) | ((c1 & 0xF) << 8) | ((s2 & 0xF) << 4) | ((c2 & 0xF) << 0);
1302
1319
}
1303
1320
 
1310
1327
        if( !data )
1311
1328
                return s;
1312
1329
 
 
1330
#define PACK_5DM3_SMALL_JPEG_SIZE( X ) (X) >= 0xd ? (X)+1 : (X)
 
1331
 
1313
1332
        htod32a(data+=0, n);
1314
1333
        htod32a(data+=4, 0x10);
1315
1334
        htod32a(data+=4, ((value >> 8) & 0xF) == 4 ? 6 : 1);
1316
 
        htod32a(data+=4, (value >> 12) & 0xF);
 
1335
        htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 12) & 0xF));
1317
1336
        htod32a(data+=4, (value >> 8) & 0xF);
1318
1337
 
1319
1338
        if (n==2) {
1320
1339
                htod32a(data+=4, 0x10);
1321
1340
                htod32a(data+=4, ((value >> 0) & 0xF) == 4 ? 6 : 1);
1322
 
                htod32a(data+=4, (value >> 4) & 0xF);
 
1341
                htod32a(data+=4, PACK_5DM3_SMALL_JPEG_SIZE((value >> 4) & 0xF));
1323
1342
                htod32a(data+=4, (value >> 0) & 0xF);
1324
1343
        }
1325
1344
 
 
1345
#undef PACK_5DM3_SMALL_JPEG_SIZE
 
1346
 
 
1347
        return s;
 
1348
}
 
1349
 
 
1350
static inline char*
 
1351
ptp_unpack_EOS_CustomFuncEx (PTPParams* params, unsigned char** data )
 
1352
{
 
1353
        uint32_t s = dtoh32a( *data );
 
1354
        uint32_t n = s/4, i;
 
1355
        char* str = (char*)malloc( s ); // n is size in uint32, average len(itoa(i)) < 4 -> alloc n chars
 
1356
        if (!str)
 
1357
                return str;
 
1358
        char* p = str;
 
1359
 
 
1360
        for (i=0; i < n; ++i)
 
1361
                p += sprintf(p, "%x,", dtoh32a( *data + 4*i ));
 
1362
 
 
1363
        return str;
 
1364
}
 
1365
 
 
1366
static inline uint32_t
 
1367
ptp_pack_EOS_CustomFuncEx (PTPParams* params, unsigned char* data, char* str)
 
1368
{
 
1369
        uint32_t s = strtoul(str, NULL, 16);
 
1370
        uint32_t n = s/4, i, v;
 
1371
 
 
1372
        if (!data)
 
1373
                return s;
 
1374
 
 
1375
        for (i=0; i<n; i++)
 
1376
        {
 
1377
                v = strtoul(str, &str, 16);
 
1378
                str++; // skip the ',' delimiter
 
1379
                htod32a(data + i*4, v);
 
1380
        }
 
1381
 
1326
1382
        return s;
1327
1383
}
1328
1384
 
1646
1702
                                case PTP_DPC_CANON_EOS_MovSize:
1647
1703
                                case PTP_DPC_CANON_EOS_DepthOfField:
1648
1704
                                case PTP_DPC_CANON_EOS_LvViewTypeSelect:
1649
 
                                case PTP_DPC_CANON_EOS_CustomFuncEx:
1650
1705
                                        dpd->DataType = PTP_DTC_UINT32;
1651
1706
                                        ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d, using uint32", i ,proptype, size-PTP_ece_Prop_Val_Data);
1652
1707
                                        if ((size-PTP_ece_Prop_Val_Data) % sizeof(uint32_t) != 0)
1659
1714
                                case PTP_DPC_CANON_EOS_ImageFormatCF:
1660
1715
                                case PTP_DPC_CANON_EOS_ImageFormatSD:
1661
1716
                                case PTP_DPC_CANON_EOS_ImageFormatExtHD:
 
1717
                                case PTP_DPC_CANON_EOS_CustomFuncEx:
1662
1718
                                        break;
1663
1719
                                default:
1664
1720
                                        ptp_debug (params, "event %d: Unknown EOS property %04x, datasize is %d", i ,proptype, size-PTP_ece_Prop_Val_Data);
1702
1758
                                        break;
1703
1759
                                }
1704
1760
 
1705
 
                                /* ImageFormat special handling (WARNING: dont move this in front of the dpd->DataType switch!) */
 
1761
                                /* ImageFormat and customFuncEx special handling (WARNING: dont move this in front of the dpd->DataType switch!) */
1706
1762
                                switch (proptype) {
1707
1763
                                case PTP_DPC_CANON_EOS_ImageFormat:
1708
1764
                                case PTP_DPC_CANON_EOS_ImageFormatCF:
1713
1769
                                        dpd->CurrentValue.u16           = dpd->FactoryDefaultValue.u16;
1714
1770
                                        ptp_debug (params,"event %d: decoded imageformat, currentvalue of %x is %x", i, proptype, dpd->CurrentValue.u16);
1715
1771
                                        break;
 
1772
                                case PTP_DPC_CANON_EOS_CustomFuncEx:
 
1773
                                        dpd->DataType = PTP_DTC_STR;
 
1774
                                        if (dpd->FactoryDefaultValue.str) free (dpd->FactoryDefaultValue.str);
 
1775
                                        if (dpd->CurrentValue.str)        free (dpd->CurrentValue.str);
 
1776
                                        dpd->FactoryDefaultValue.str    = ptp_unpack_EOS_CustomFuncEx( params, &data );
 
1777
                                        dpd->CurrentValue.str           = strdup( (char*)dpd->FactoryDefaultValue.str );
 
1778
                                        ptp_debug (params,"event %d: decoded custom function, currentvalue of %x is %s", i, proptype, dpd->CurrentValue.str);
 
1779
                                        break;
1716
1780
                                }
1717
1781
 
1718
1782
                                break;