ptp-pack.c
来自「Media transfer protocol implementation o」· C语言 代码 · 共 1,202 行 · 第 1/3 页
C
1,202 行
dpv=malloc(size); htod32a(dpv,value->a.count); for (i=0;i<value->a.count;i++) htod16a(&dpv[4+i],value->a.v[i].i16); break; case PTP_DTC_AUINT32: size=sizeof(uint32_t)+value->a.count*sizeof(uint32_t); dpv=malloc(size); htod32a(dpv,value->a.count); for (i=0;i<value->a.count;i++) htod32a(&dpv[4+i],value->a.v[i].u32); break; case PTP_DTC_AINT32: size=sizeof(uint32_t)+value->a.count*sizeof(int32_t); dpv=malloc(size); htod32a(dpv,value->a.count); for (i=0;i<value->a.count;i++) htod32a(&dpv[4+i],value->a.v[i].i32); break; /* XXX: other int types are unimplemented */ case PTP_DTC_STR: { dpv=ptp_get_packed_stringcopy(params, value->str, &size); break; } } *dpvptr=dpv; return size;}#define MAX_MTP_PROPS 127static inline uint32_tptp_pack_OPL (PTPParams *params, MTPPropList *proplist, unsigned char** opldataptr){ unsigned char* opldata; MTPPropList *propitr; unsigned char *packedprops[MAX_MTP_PROPS]; uint32_t packedpropslens[MAX_MTP_PROPS]; uint32_t packedobjecthandles[MAX_MTP_PROPS]; uint16_t packedpropsids[MAX_MTP_PROPS]; uint16_t packedpropstypes[MAX_MTP_PROPS]; uint32_t totalsize = 0; uint32_t bufp = 0; uint32_t noitems = 0; uint32_t i; totalsize = sizeof(uint32_t); /* 4 bytes to store the number of elements */ propitr = proplist; while (propitr != NULL && noitems < MAX_MTP_PROPS) { /* Object Handle */ packedobjecthandles[noitems]=propitr->ObjectHandle; totalsize += sizeof(uint32_t); /* Object ID */ /* Metadata type */ packedpropsids[noitems]=propitr->property; totalsize += sizeof(uint16_t); /* Data type */ packedpropstypes[noitems]= propitr->datatype; totalsize += sizeof(uint16_t); /* Add each property to be sent. */ packedpropslens[noitems] = ptp_pack_DPV (params, &propitr->propval, &packedprops[noitems], propitr->datatype); totalsize += packedpropslens[noitems]; noitems ++; propitr = propitr->next; } /* Allocate memory for the packed property list */ opldata = malloc(totalsize); htod32a(&opldata[bufp],noitems); bufp += 4; /* Copy into a nice packed list */ for (i = 0; i < noitems; i++) { /* Object ID */ htod32a(&opldata[bufp],packedobjecthandles[i]); bufp += sizeof(uint32_t); htod16a(&opldata[bufp],packedpropsids[i]); bufp += sizeof(uint16_t); htod16a(&opldata[bufp],packedpropstypes[i]); bufp += sizeof(uint16_t); /* The copy the actual property */ memcpy(&opldata[bufp], packedprops[i], packedpropslens[i]); bufp += packedpropslens[i]; free(packedprops[i]); } *opldataptr = opldata; return totalsize;}static inline intptp_unpack_OPL (PTPParams *params, unsigned char* data, MTPPropList **proplist, unsigned int len){ uint32_t prop_count = dtoh32a(data); MTPPropList *prop = NULL; int offset = 0, i; if (prop_count == 0) { *proplist = NULL; return 0; } data += sizeof(uint32_t); *proplist = malloc(sizeof(MTPPropList)); prop = *proplist; for (i = 0; i < prop_count; i++) { prop->ObjectHandle = dtoh32a(data); data += sizeof(uint32_t); len -= sizeof(uint32_t); prop->property = dtoh16a(data); data += sizeof(uint16_t); len -= sizeof(uint16_t); prop->datatype = dtoh16a(data); data += sizeof(uint16_t); len -= sizeof(uint16_t); offset = 0; ptp_unpack_DPV(params, data, &offset, len, &prop->propval, prop->datatype); data += offset; len -= offset; if (i != prop_count - 1) { prop->next = malloc(sizeof(MTPPropList)); prop = prop->next; } else prop->next = NULL; } return prop_count;}/* PTP USB Event container unpack Copyright (c) 2003 Nikolai Kopanygin*/#define PTP_ec_Length 0#define PTP_ec_Type 4#define PTP_ec_Code 6#define PTP_ec_TransId 8#define PTP_ec_Param1 12#define PTP_ec_Param2 16#define PTP_ec_Param3 20static inline voidptp_unpack_EC (PTPParams *params, unsigned char* data, PTPUSBEventContainer *ec, unsigned int len){ if (data==NULL) return; ec->length=dtoh32a(&data[PTP_ec_Length]); ec->type=dtoh16a(&data[PTP_ec_Type]); ec->code=dtoh16a(&data[PTP_ec_Code]); ec->trans_id=dtoh32a(&data[PTP_ec_TransId]); if (ec->length>=(PTP_ec_Param1+4)) ec->param1=dtoh32a(&data[PTP_ec_Param1]); else ec->param1=0; if (ec->length>=(PTP_ec_Param2+4)) ec->param2=dtoh32a(&data[PTP_ec_Param2]); else ec->param2=0; if (ec->length>=(PTP_ec_Param3+4)) ec->param3=dtoh32a(&data[PTP_ec_Param3]); else ec->param3=0;}/* PTP Canon Folder Entry unpack Copyright (c) 2003 Nikolai Kopanygin*/#define PTP_cfe_ObjectHandle 0#define PTP_cfe_ObjectFormatCode 4#define PTP_cfe_Flags 6#define PTP_cfe_ObjectSize 7#define PTP_cfe_Time 11#define PTP_cfe_Filename 15static inline voidptp_unpack_Canon_FE (PTPParams *params, unsigned char* data, PTPCANONFolderEntry *fe){ int i; if (data==NULL) return; fe->ObjectHandle=dtoh32a(&data[PTP_cfe_ObjectHandle]); fe->ObjectFormatCode=dtoh16a(&data[PTP_cfe_ObjectFormatCode]); fe->Flags=dtoh8a(&data[PTP_cfe_Flags]); fe->ObjectSize=dtoh32a((unsigned char*)&data[PTP_cfe_ObjectSize]); fe->Time=(time_t)dtoh32a(&data[PTP_cfe_Time]); for (i=0; i<PTP_CANON_FilenameBufferLen; i++) fe->Filename[i]=(char)dtoh8a(&data[PTP_cfe_Filename+i]);}/* PTP USB Event container unpack for Nikon events.*/#define PTP_nikon_ec_Length 0#define PTP_nikon_ec_Code 2#define PTP_nikon_ec_Param1 4#define PTP_nikon_ec_Size 6static inline voidptp_unpack_Nikon_EC (PTPParams *params, unsigned char* data, unsigned int len, PTPUSBEventContainer **ec, int *cnt){ int i; *ec = NULL; if (data == NULL) return; if (len < PTP_nikon_ec_Code) return; *cnt = dtoh16a(&data[PTP_nikon_ec_Length]); if (*cnt > (len-PTP_nikon_ec_Code)/PTP_nikon_ec_Size) /* broken cnt? */ return; *ec = malloc(sizeof(PTPUSBEventContainer)*(*cnt)); for (i=0;i<*cnt;i++) { memset(&(*ec)[i],0,sizeof(PTPUSBEventContainer)); (*ec)[i].code = dtoh16a(&data[PTP_nikon_ec_Code+PTP_nikon_ec_Size*i]); (*ec)[i].param1 = dtoh32a(&data[PTP_nikon_ec_Param1+PTP_nikon_ec_Size*i]); }}static inline uint32_tptp_pack_EK_text(PTPParams *params, PTPEKTextParams *text, unsigned char **data) { int i, len = 0; uint8_t retlen; unsigned char *curdata; len = 2*(strlen(text->title)+1)+1+ 2*(strlen(text->line[0])+1)+1+ 2*(strlen(text->line[1])+1)+1+ 2*(strlen(text->line[2])+1)+1+ 2*(strlen(text->line[3])+1)+1+ 2*(strlen(text->line[4])+1)+1+ 4*2+2*4+2+4+2+5*4*2; *data = malloc(len); if (!*data) return 0; curdata = *data; htod16a(curdata,100);curdata+=2; htod16a(curdata,1);curdata+=2; htod16a(curdata,0);curdata+=2; htod16a(curdata,1000);curdata+=2; htod32a(curdata,0);curdata+=4; htod32a(curdata,0);curdata+=4; htod16a(curdata,6);curdata+=2; htod32a(curdata,0);curdata+=4; ptp_pack_string(params, text->title, curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; htod16a(curdata,0x10);curdata+=2; for (i=0;i<5;i++) { ptp_pack_string(params, text->line[i], curdata, 0, &retlen); curdata+=2*retlen+1;htod16a(curdata,0);curdata+=2; htod16a(curdata,0x10);curdata+=2; htod16a(curdata,0x01);curdata+=2; htod16a(curdata,0x02);curdata+=2; htod16a(curdata,0x06);curdata+=2; } return len;}#define ptp_canon_dir_version 0x00#define ptp_canon_dir_ofc 0x02#define ptp_canon_dir_unk1 0x04#define ptp_canon_dir_objectid 0x08#define ptp_canon_dir_parentid 0x0c#define ptp_canon_dir_previd 0x10 /* in same dir */#define ptp_canon_dir_nextid 0x14 /* in same dir */#define ptp_canon_dir_nextchild 0x18 /* down one dir */#define ptp_canon_dir_storageid 0x1c /* only in storage entry */#define ptp_canon_dir_name 0x20#define ptp_canon_dir_flags 0x2c#define ptp_canon_dir_size 0x30#define ptp_canon_dir_unixtime 0x34#define ptp_canon_dir_year 0x38#define ptp_canon_dir_month 0x39#define ptp_canon_dir_mday 0x3a#define ptp_canon_dir_hour 0x3b#define ptp_canon_dir_minute 0x3c#define ptp_canon_dir_second 0x3d#define ptp_canon_dir_unk2 0x3e#define ptp_canon_dir_thumbsize 0x40#define ptp_canon_dir_width 0x44#define ptp_canon_dir_height 0x48static inline uint16_tptp_unpack_canon_directory ( PTPParams *params, unsigned char *dir, uint32_t cnt, PTPObjectHandles *handles, PTPObjectInfo **oinfos, /* size(handles->n) */ uint32_t **flags /* size(handles->n) */) { unsigned int i, j, nrofobs = 0, curob = 0;#define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff) for (i=0;i<cnt;i++) if (ISOBJECT(dir+i*0x4c)) nrofobs++; handles->n = nrofobs; handles->Handler = calloc(sizeof(handles->Handler[0]),nrofobs); if (!handles->Handler) return PTP_RC_GeneralError; *oinfos = calloc(sizeof((*oinfos)[0]),nrofobs); if (!*oinfos) return PTP_RC_GeneralError; *flags = calloc(sizeof((*flags)[0]),nrofobs); if (!*flags) return PTP_RC_GeneralError; /* Migrate data into objects ids, handles into * the object handler array. */ curob = 0; for (i=0;i<cnt;i++) { unsigned char *cur = dir+i*0x4c; PTPObjectInfo *oi = (*oinfos)+curob; if (!ISOBJECT(cur)) continue; handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid); oi->StorageID = 0xffffffff; oi->ObjectFormat = dtoh16a(cur + ptp_canon_dir_ofc); oi->ParentObject = dtoh32a(cur + ptp_canon_dir_parentid); oi->Filename = strdup((char*)(cur + ptp_canon_dir_name)); oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size); oi->ThumbCompressedSize = dtoh32a(cur + ptp_canon_dir_thumbsize); oi->ImagePixWidth = dtoh32a(cur + ptp_canon_dir_width); oi->ImagePixHeight = dtoh32a(cur + ptp_canon_dir_height); oi->CaptureDate = oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime); (*flags)[curob] = dtoh32a(cur + ptp_canon_dir_flags); curob++; } /* Walk over Storage ID entries and distribute the IDs to * the parent objects. */ for (i=0;i<cnt;i++) { unsigned char *cur = dir+i*0x4c; uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); if (ISOBJECT(cur)) continue; for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; if (j == handles->n) continue; (*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid); } /* Walk over all objects and distribute the storage ids */ while (1) { int changed = 0; for (i=0;i<cnt;i++) { unsigned char *cur = dir+i*0x4c; uint32_t oid = dtoh32a(cur + ptp_canon_dir_objectid); uint32_t nextoid = dtoh32a(cur + ptp_canon_dir_nextid); uint32_t nextchild = dtoh32a(cur + ptp_canon_dir_nextchild); uint32_t storageid; if (!ISOBJECT(cur)) continue; for (j=0;j<handles->n;j++) if (oid == handles->Handler[j]) break; if (j == handles->n) { /*fprintf(stderr,"did not find oid in lookup pass for current oid\n");*/ continue; } storageid = (*oinfos)[j].StorageID; if (storageid == 0xffffffff) continue; if (nextoid != 0xffffffff) { for (j=0;j<handles->n;j++) if (nextoid == handles->Handler[j]) break; if (j == handles->n) { /*fprintf(stderr,"did not find oid in lookup pass for next oid\n");*/ continue; } if ((*oinfos)[j].StorageID == 0xffffffff) { (*oinfos)[j].StorageID = storageid; changed++; } } if (nextchild != 0xffffffff) { for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break; if (j == handles->n) { /*fprintf(stderr,"did not find oid in lookup pass for next child\n");*/ continue; } if ((*oinfos)[j].StorageID == 0xffffffff) { (*oinfos)[j].StorageID = storageid; changed++; } } } /* Check if we: * - changed no entry (nothing more to do) * - changed all of them at once (usually happens) * break if we do. */ if (!changed || (changed==nrofobs-1)) break; }#undef ISOBJECT return PTP_RC_OK;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?