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 + -
显示快捷键?