/** * Takes an initialized asf_file_t structure file as a parameter. Allocates * a new asf_object_data_t in file->data and uses the file->iostream to * read all its compulsory fields into it. Notice that the actual data is * not read in any way, because we need to be able to work with non-seekable * streams as well. */ int asf_parse_data(asf_file_t *file) { asf_object_data_t *data; asf_iostream_t *iostream; uint8_t ddata[50]; int tmp; file->data = NULL; iostream = &file->iostream; /* object minimum is 24 bytes and data object needs to have * 26 additional bytes for its internal fields */ tmp = asf_byteio_read(iostream, ddata, 50); if (tmp < 0) { return tmp; } file->data = malloc(sizeof(asf_object_data_t)); data = file->data; if (!data) { return ASF_ERROR_OUTOFMEM; } /* read the object and check its size value */ asf_parse_read_object((asfint_object_t *) data, ddata); if (data->size < 50) { /* invalid size for data object */ return ASF_ERROR_INVALID_OBJECT_SIZE; } /* read data object specific compulsory fields */ GetGUID(ddata + 24, &data->file_id); data->total_data_packets = GetQWLE(ddata + 40); data->reserved = GetWLE(ddata + 48); data->packets_position = file->position + 50; /* If the file_id GUID in data object doesn't match the * file_id GUID in headers, the file is corrupted */ if (!asf_guid_equals(&data->file_id, &file->file_id)) { return ASF_ERROR_INVALID_VALUE; } /* if data->total_data_packets is non-zero (not a stream) and the data packets count doesn't match, return error */ if (data->total_data_packets && data->total_data_packets != file->data_packets_count) { return ASF_ERROR_INVALID_VALUE; } return 50; }
//main entry of parsing index object //int64_t next_index_position is the cuurent file postion to find index int ASFParser::asf_parse_index(int64_t next_index_position) { asf_object_index_t *index = NULL; asf_iostream_t *iostream = NULL; int64_t seek_position=0; uint8_t idata[24]; int tmp =-1; ALOGI("-----asf_parse_index----"); iostream = &file->iostream; //from the file->index_postion read 24 byte : GUID+size //obj min is 24 byte size tmp = ASFByteIO::asf_byteio_read(idata, 24, iostream); if (tmp < 0) { ALOGE("asf_parse_index:error1 tmp=%d",tmp); return tmp;//ASF_ERROR_EOF or ASF_ERROR_IO; } ALOGI("asf_parse_index:tmp1=%d",tmp); // allocate the index object index = (asf_object_index_t*)calloc(1,sizeof(asf_object_index_t)); if (!index) { ALOGE("asf_parse_index:ASF_ERROR_OUTOFMEM 0\n"); return ASF_ERROR_OUTOFMEM; } asf_parse_read_object((asfint_object_t *) index, idata); if (index->type != GUID_INDEX && index->type != GUID_SIMPLE_INDEX ) { tmp = index->size; free(index); // The guid type was wrong, just return the bytes to skip return (tmp == 0) ? ASF_ERROR_EOF : tmp; //return tmp; } else { //GUID_INDEX || GUID_SIMPLE_INDEX //back to the start postion to parse this index seek_position = file->iostream.seek(file->iostream.source, next_index_position); if (index->type == GUID_SIMPLE_INDEX) { tmp = asf_parse_index_simple_index(); } if (index->type == GUID_INDEX) { tmp = asf_parse_index_index(); } } free(index);// re-parser the index return tmp; }
/** * Parse header extension object. Takes a pointer to a newly allocated * header extension structure, a pointer to the data buffer and the * length of the data buffer as its parameters. Subobject contents are * not parsed, but they are added as a linked list to the header object. */ static int asf_parse_headerext(asf_object_headerext_t *header, uint8_t *buf, uint64_t buflen) { int64_t datalen; uint8_t *data; if (header->size < 46) { /* invalide size for headerext */ return ASF_ERROR_INVALID_OBJECT_SIZE; } /* Read reserved and datalen fields from the buffer */ GetGUID(buf + 24, &header->reserved1); header->reserved2 = GetWLE(buf + 40); header->datalen = GetDWLE(buf + 42); if (header->datalen != header->size - 46) { /* invalid header extension data length value */ return ASF_ERROR_INVALID_LENGTH; } header->data = buf + 46; debug_printf("parsing header extension subobjects"); datalen = header->datalen; data = header->data; while (datalen > 0) { asfint_object_t *current; if (datalen < 24) { /* not enough data for reading a new object */ break; } /* Allocate a new subobject */ current = malloc(sizeof(asfint_object_t)); if (!current) { return ASF_ERROR_OUTOFMEM; } asf_parse_read_object(current, data); if (current->size > datalen || current->size < 24) { /* invalid object size */ break; } current->datalen = current->size - 24; current->data = data + 24; /* add to the list of subobjects */ if (!header->first) { header->first = current; header->last = current; } else { header->last->next = current; header->last = current; } data += current->size; datalen -= current->size; } if (datalen != 0) { /* not enough data for reading the whole object */ return ASF_ERROR_INVALID_LENGTH; } debug_printf("header extension subobjects parsed successfully"); return header->size; }
/** * Takes an initialized asf_file_t structure file as a parameter. Allocates * a new asf_object_index_t in file->index and uses the file->iostream to * read all its compulsory fields into it. Notice that the actual data is * not read in any way, because we need to be able to work with non-seekable * streams as well. */ int asf_parse_index(asf_file_t *file) { asf_object_index_t *index; asf_iostream_t *iostream; uint8_t idata[56]; uint64_t entry_data_size; uint8_t *entry_data = NULL; int tmp, i; file->index = NULL; iostream = &file->iostream; /* read the raw data of an index header */ tmp = asf_byteio_read(iostream, idata, 56); if (tmp < 0) { printf("Could not read index header\n"); return tmp; } /* allocate the index object */ index = malloc(sizeof(asf_object_index_t)); if (!index) { return ASF_ERROR_OUTOFMEM; } asf_parse_read_object((asfint_object_t *) index, idata); if (index->type != GUID_INDEX) { tmp = index->size; free(index); /* The guid type was wrong, just return the bytes to skip */ return tmp; } if (index->size < 56) { /* invalid size for index object */ free(index); return ASF_ERROR_INVALID_OBJECT_SIZE; } GetGUID(idata + 24, &index->file_id); index->entry_time_interval = GetQWLE(idata + 40); index->max_packet_count = GetDWLE(idata + 48); index->entry_count = GetDWLE(idata + 52); printf("INDEX\n"); printf("Total Index Entries %d\n",index->entry_count); printf("Index Size in bytes %Ld\n",index->size); printf("Index Max Packet Count %d\n",index->max_packet_count); printf("Index Entry Time Interval %Ld\n",index->entry_time_interval); if (index->entry_count == 0) { printf("Index has no entries\n"); file->index = index; return index->size; } if (index->entry_count * 6 + 56 > index->size) { free(index); return ASF_ERROR_INVALID_LENGTH; } entry_data_size = index->entry_count * 6; entry_data = malloc(entry_data_size * sizeof(uint8_t)); if (!entry_data) { free(index); return ASF_ERROR_OUTOFMEM; } tmp = asf_byteio_read(iostream, entry_data, entry_data_size); if (tmp < 0) { printf("Could not read entry data\n"); free(index); free(entry_data); return tmp; } index->entries = malloc(index->entry_count * sizeof(asf_index_entry_t)); if (!index->entries) { free(index); free(entry_data); return ASF_ERROR_OUTOFMEM; } for (i=0; i<index->entry_count; i++) { index->entries[i].packet_index = GetDWLE(entry_data + i*6); index->entries[i].packet_count = GetWLE(entry_data + i*6 + 4); } free(entry_data); file->index = index; return index->size; }
/** * Takes an initialized asf_file_t structure file as a parameter. Allocates * a new asf_object_header_t in file->header and uses the file->iostream to * read all fields and subobjects into it. Finally calls the * asf_parse_header_validate function to validate the values and parse the * commonly used values into the asf_file_t struct itself. */ int asf_parse_header(asf_file_t *file) { asf_object_header_t *header; asf_iostream_t *iostream; uint8_t hdata[30]; int tmp; file->header = NULL; iostream = &file->iostream; /* object minimum is 24 bytes and header needs to have * the subobject count field and two reserved fields */ tmp = asf_byteio_read(iostream, hdata, 30); if (tmp < 0) { /* not enough data to read the header object */ return tmp; } file->header = malloc(sizeof(asf_object_header_t)); header = file->header; if (!header) { return ASF_ERROR_OUTOFMEM; } /* read the object and check its size value */ asf_parse_read_object((asfint_object_t *) header, hdata); if (header->size < 30) { /* invalid size for header object */ return ASF_ERROR_INVALID_OBJECT_SIZE; } /* read header object specific compulsory fields */ header->subobjects = GetDWLE(hdata + 24); header->reserved1 = hdata[28]; header->reserved2 = hdata[29]; /* clear header extension object and subobject list */ header->ext = NULL; header->first = NULL; header->last = NULL; /* the header data needs to be allocated for reading */ header->datalen = header->size - 30; header->data = malloc(header->datalen * sizeof(uint8_t)); if (!header->data) { return ASF_ERROR_OUTOFMEM; } tmp = asf_byteio_read(iostream, header->data, header->datalen); if (tmp < 0) { return tmp; } if (header->subobjects > 0) { uint64_t datalen; uint8_t *data; int i; debug_printf("starting to read subobjects"); /* use temporary variables for use during the read */ datalen = header->datalen; data = header->data; for (i=0; i<header->subobjects; i++) { asfint_object_t *current; if (datalen < 24) { /* not enough data for reading object */ break; } current = malloc(sizeof(asfint_object_t)); if (!current) { return ASF_ERROR_OUTOFMEM; } asf_parse_read_object(current, data); if (current->size > datalen || current->size < 24) { /* invalid object size */ break; } /* Check if the current subobject is a header extension * object or just a normal subobject */ if (current->type == GUID_HEADER_EXTENSION && !header->ext) { int ret; asf_object_headerext_t *headerext; /* we handle header extension separately because it has * some subobjects as well */ current = realloc(current, sizeof(asf_object_headerext_t)); headerext = (asf_object_headerext_t *) current; headerext->first = NULL; headerext->last = NULL; ret = asf_parse_headerext(headerext, data, datalen); if (ret < 0) { /* error parsing header extension */ return ret; } header->ext = headerext; } else { if (current->type == GUID_HEADER_EXTENSION) { debug_printf("WARNING! Second header extension object found, ignoring it!"); } current->datalen = current->size - 24; current->data = data + 24; /* add to list of subobjects */ if (!header->first) { header->first = current; header->last = current; } else { header->last->next = current; header->last = current; } } data += current->size; datalen -= current->size; } if (i != header->subobjects || datalen != 0) { /* header data size doesn't match given subobject count */ return ASF_ERROR_INVALID_VALUE; } debug_printf("%d subobjects read successfully", i); } tmp = asf_parse_header_validate(file, file->header); if (tmp < 0) { /* header read ok but doesn't validate correctly */ return tmp; } debug_printf("header validated correctly"); return header->size; }
int ASFParser::asf_parse_index_index() { asf_object_index_t *index = NULL; asf_iostream_t *iostream = NULL; uint8_t idata[34]; uint64_t specifiers_data_size; uint8_t *specifiers_data = NULL; int tmp =-1; uint32_t i; ALOGI("-----asf_parse_index_index----"); file->index = NULL; iostream = &file->iostream; memset(idata, 0, 34); tmp = ASFByteIO::asf_byteio_read(idata, 34, iostream); if (tmp < 0) { return tmp; } // allocate the index object index = (asf_object_index_t*)calloc(1,sizeof(asf_object_index_t)); if (!index) { ALOGE("asf_parse_index_index:ASF_ERROR_OUTOFMEM 0\n"); return ASF_ERROR_OUTOFMEM; } asf_parse_read_object((asfint_object_t *) index, idata); if (index->type != GUID_INDEX) { tmp = index->size; free(index); ALOGE(" index->type != GUID_INDEX The guid type was wrong, just return the bytes to skip \n"); // The guid type was wrong, just return the bytes to skip return (tmp == 0) ? ASF_ERROR_EOF : tmp; } if (index->size < 34) { // invalid size for index object free(index); ALOGE("[ASF_ERROR]asf_parse_index_index: ASF_ERROR_OBJECT_SIZE 1\n"); return ASF_ERROR_OBJECT_SIZE; } //in 100-nanosecond units. index->index_entry_time_interval = ASFByteIO::asf_byteio_getQWLE(idata + 24); index->index_specifies_count= ASFByteIO::asf_byteio_getWLE(idata + 28); index->index_block_count= ASFByteIO::asf_byteio_getDWLE(idata + 30); if (index->index_block_count>1) { tmp=index->size; // to make sure we can parser next index free(index); ALOGE("index_block_count=%d >1, not support now\n",index->index_block_count); return (tmp == 0) ? ASF_ERROR_EOF : tmp; } else if (index->index_specifies_count>1) { tmp=index->size; // to make sure we can parser next index //free(index); //ALOGE("index_specifies_count=%d >1, not support now\n",index->index_specifies_count); //return (tmp == 0) ? ASF_ERROR_EOF : tmp; } //right? check the min size if ((34 + index->index_block_count * 16 + index->index_specifies_count * 4) > index->size) { free(index); ALOGE("[ASF_ERROR]parse index object:invalid size 2 \n"); return ASF_ERROR_INVALID_LENGTH; } //Index Specifiers specifiers_data_size = index->index_specifies_count * sizeof(asf_index_specifiers_t); specifiers_data = (uint8_t*)calloc(1,specifiers_data_size*sizeof(uint8_t)); if (!specifiers_data) { free(index); ALOGE("[ASF_ERROR]ASF_ERROR_OUTOFMEM for index object 1 \n"); return ASF_ERROR_OUTOFMEM; } //read specifiers_data tmp = ASFByteIO::asf_byteio_read(specifiers_data, specifiers_data_size, iostream); if (tmp < 0) { free(index); free(specifiers_data); return tmp; } ALOGI("---index_specifies_count =%d---\n", index->index_specifies_count); index->specifiers_entry= (asf_index_specifiers_t*)calloc(1,specifiers_data_size); if (!index->specifiers_entry) { free(index); free(specifiers_data); ALOGE("[ASF_ERROR]ASF_ERROR_OUTOFMEM for index->specifiers_entry \n"); return ASF_ERROR_OUTOFMEM; } for (i=0;i<index->index_specifies_count;i++) { ((asf_index_specifiers_s*)index->specifiers_entry)->stream_num = ASFByteIO::asf_byteio_getWLE((specifiers_data) + 4 * i); ((asf_index_specifiers_s*)index->specifiers_entry)->index_type = ASFByteIO::asf_byteio_getWLE((specifiers_data + 2) + 4 * i); ALOGI("---index_specifiers_entry[%d].stream_num=%d,index_specifiers_entry[%d].type=%d---\n", i, ((asf_index_specifiers_s*)index->specifiers_entry)->stream_num, i, ((asf_index_specifiers_s*)index->specifiers_entry)->index_type); } free(specifiers_data); //Index Blocks, just 1 count uint32_t block_count; uint32_t index_entry_count; uint64_t index_block_position; uint8_t *block_data = NULL; uint64_t entry_data_size; uint8_t *entry_data = NULL; block_count = index->index_block_count; if (NULL == file->header->index_parameters) { ALOGI("[ASF_ERROR] file->header->index_parameters null point"); return ASF_ERROR_OBJECT_SIZE; } block_data = (uint8_t*)calloc(1, (4 + file->header->index_parameters->index_specifiers_count * 8) * sizeof(uint8_t)); //parser 1ht blocks tmp = ASFByteIO::asf_byteio_read(block_data, 4 + file->header->index_parameters->index_specifiers_count * 8, iostream); if (tmp < 0) { free(index); return tmp; } index_entry_count =ASFByteIO::asf_byteio_getDWLE(block_data); ALOGI("---Index Blocks,:index_entry_count=%d----\n",index_entry_count); index_block_position =ASFByteIO::asf_byteio_getDWLE(block_data + 4); ALOGI("---Index Blocks,:index_block_position=%lld----\n",index_block_position); entry_data_size = index_entry_count * (file->header->index_parameters->index_specifiers_count *4); entry_data = (uint8_t*)calloc(1,entry_data_size * sizeof(uint8_t)); if (!entry_data) { free(index->specifiers_entry); free(index); ALOGE("[ASF_ERROR]ASF_ERROR_OUTOFMEM for index object2 \n"); return ASF_ERROR_OUTOFMEM; } tmp = ASFByteIO::asf_byteio_read(entry_data, entry_data_size, iostream); if (tmp < 0) { free(index->specifiers_entry); free(index); return tmp; } index->index_block = (asf_index_blocks_s *)calloc(1,sizeof(asf_index_blocks_s)); //entry_count 4+ Block Positions 8 + entry pointer 4 if (!index->index_block) { free(index->specifiers_entry); free(index); free(entry_data); ALOGE("[ASF_ERROR]ASF_ERROR_OUTOFMEM for index object 3 \n"); return ASF_ERROR_OUTOFMEM; } index->index_block->index_entry_count = index_entry_count; index->index_block->block_positions =index_block_position; index->index_block->index_entry = (asf_index_entry_s *)calloc(1, index_entry_count * sizeof(asf_index_entry_s)); if (!index->index_block->index_entry ) { free(index->specifiers_entry); free(index->index_block); free(entry_data); free(index); ALOGE("[ASF_ERROR]ASF_ERROR_OUTOFMEM for index object 3 \n"); return ASF_ERROR_OUTOFMEM; } for (i=0;i<index_entry_count;i++) { if (ASF_STREAM_TYPE_VIDEO == file->streams[1].type) { index->index_block->index_entry[i].offset = ASFByteIO::asf_byteio_getDWLE(entry_data + i*(file->header->index_parameters->index_specifiers_count * 4)); } else { index->index_block->index_entry[i].offset = ASFByteIO::asf_byteio_getDWLE(entry_data + i*(file->header->index_parameters->index_specifiers_count * 4) + 4); } if (index->index_block->index_entry[i].offset >= file->file_size) { index->index_block->index_entry[i].offset = 0; } ALOGI("%d entry offset =%d\n",i,index->index_block->index_entry[i].offset); } free(entry_data); free(block_data); file->index = index; return index->size; }
/** * Takes an initialized asf_file_t structure file as a parameter. Allocates * a new asf_object_index_t in file->index and uses the file->iostream to * read all its compulsory fields into it. Notice that the actual data is * not read in any way, because we need to be able to work with non-seekable * streams as well. */ int ASFParser::asf_parse_index_simple_index() { asf_object_simple_index_t *simple_index = NULL; asf_iostream_t *iostream = NULL; uint8_t idata[56]; uint64_t entry_data_size; uint8_t *entry_data = NULL; int tmp; uint32_t i; ALOGI("-----asf_parse_index_simple_index----"); file->simple_index = NULL; iostream = &file->iostream; memset(idata, 0, 56); // Morris Yang 6.1 Page 57 /* read the raw data of an index header */ tmp = ASFByteIO::asf_byteio_read(idata, 56, iostream); if (tmp < 0) { ALOGE("asf_parse_index_simple_index:error 1\n"); return tmp; } /* allocate the index object */ simple_index = (asf_object_simple_index_t*)malloc(sizeof(asf_object_simple_index_t)); if (!simple_index) { return ASF_ERROR_OUTOFMEM; } memset(simple_index, 0, sizeof(asf_object_simple_index_t)); asf_parse_read_object((asfint_object_t *) simple_index, idata); if (simple_index->type != GUID_SIMPLE_INDEX) { tmp = simple_index->size; free(simple_index); ALOGE("index->type != GUID_SIMPLE_INDEX The guid type was wrong, just return the bytes to skip\n"); /* The guid type was wrong, just return the bytes to skip */ return (tmp == 0) ? ASF_ERROR_EOF : ASF_ERROR_IO; } if (simple_index->size < 56) { /* invalid size for index object */ free(simple_index); ALOGE("[ASF_ERROR]invalid size 1 for index object\n"); return ASF_ERROR_OBJECT_SIZE; } ASFByteIO::asf_byteio_getGUID(&simple_index->file_id, idata + 24); simple_index->entry_time_interval = ASFByteIO::asf_byteio_getQWLE(idata + 40); //in 100-nanosecond units. simple_index->max_packet_count = ASFByteIO::asf_byteio_getDWLE(idata + 48); simple_index->entry_count = ASFByteIO::asf_byteio_getDWLE(idata + 52); if (simple_index->entry_count * 6 + 56 > simple_index->size) { //entry_count:packet num 32 +packet count16 =6byte free(simple_index); ALOGE("[ASF_ERROR]invalid size 2 for index object\n"); return ASF_ERROR_INVALID_LENGTH; } entry_data_size = simple_index->entry_count * 6; entry_data = (uint8_t*)malloc(entry_data_size * sizeof(uint8_t)); if (!entry_data) { free(simple_index); ALOGE("[ASF_ERROR]ASF_ERROR_OUTOFMEM for index object\n"); return ASF_ERROR_OUTOFMEM; } memset(entry_data, 0, entry_data_size * sizeof(uint8_t)); tmp = ASFByteIO::asf_byteio_read(entry_data, entry_data_size, iostream); if (tmp < 0) { free(simple_index); free(entry_data); ALOGE("asf_parse_index_simple_index:error 2\n"); return tmp; } //ALOGD ("@@ index->entry_count = %d, index->entry_time_interval = %d\n", index->entry_count, // index->entry_time_interval); simple_index->entries = (asf_simple_index_entry_t*)malloc(simple_index->entry_count * sizeof(asf_simple_index_entry_t)); if (!simple_index->entries) { free(simple_index); free(entry_data); ALOGE("asf_parse_index_simple_index:error 3\n"); return ASF_ERROR_OUTOFMEM; } memset(simple_index->entries, 0, simple_index->entry_count * sizeof(asf_simple_index_entry_t)); for (i=0; i<simple_index->entry_count; i++) { simple_index->entries[i].packet_index = ASFByteIO::asf_byteio_getDWLE(entry_data + i*6); simple_index->entries[i].packet_count = ASFByteIO::asf_byteio_getWLE(entry_data + i*6 + 4); //ALOGD ("@@ entries[%d] packet_index = %d, packet_count = %d\n", i, // index->entries[i].packet_index, index->entries[i].packet_count); } free(entry_data); file->simple_index = simple_index; return simple_index->size; }
/** * Takes an initialized asf_file_t structure file as a parameter. Allocates * a new asf_object_header_t in file->header and uses the file->iostream to * read all fields and subobjects into it. Finally calls the * asf_parse_header_validate function to validate the values and parse the * commonly used values into the asf_file_t struct itself. */ int ASFParser::asf_parse_header() { asf_object_header_t *header = NULL; asf_iostream_t *iostream = NULL; uint8_t hdata[30]; int tmp; file->header = NULL; iostream = &file->iostream; /* object minimum is 24 bytes and header needs to have * the subobject count field and two reserved fields */ memset(hdata, 0, 30); tmp = ASFByteIO::asf_byteio_read(hdata, 30, iostream); if (tmp < 0) { /* not enough data to read the header object */ ALOGE("asf_parse_header:error 1\n"); return tmp; } file->header = (asf_object_header_t*)malloc(sizeof(asf_object_header_t)); if (!file->header) { return ASF_ERROR_OUTOFMEM; } memset(file->header, 0, sizeof(asf_object_header_t)); header = file->header; /* clear header extension object and subobject list */ header->ext = NULL; header->first = NULL; header->last = NULL; /* read the object and check its size value */ asf_parse_read_object((asfint_object_t *) header, hdata); if (header->size < 30) { /* invalid size for header object */ ALOGE("asf_parse_header:error 2\n"); return ASF_ERROR_OBJECT_SIZE; } /* to check not ASF file type */ if (header->type == GUID_UNKNOWN) { /* invalid GUID for header object */ return ASF_ERROR_INVALID_VALUE; } /* read header object specific compulsory fields */ header->subobjects = ASFByteIO::asf_byteio_getDWLE(hdata + 24);//sub header object number header->reserved1 = hdata[28]; header->reserved2 = hdata[29]; header->datalen = header->size - 30; //seek to Data Object and check if Data Object follows by Header Object { file->iostream.seek(iostream->source, header->size); //read 50B from data_object asfint_object_t *data = NULL; uint8_t ddata[50]; int tmp; memset(ddata, 0, 50); /* object minimum is 24 bytes and data object needs to have * 26 additional bytes for its internal fields */ tmp = ASFByteIO::asf_byteio_read(ddata, 50, iostream); if (tmp < 0) { ALOGI("read data 50B error"); return tmp; } data = (asfint_object_t*)calloc(1,sizeof(asfint_object_t)); if (!data) { return ASF_ERROR_OUTOFMEM; } asf_parse_read_object((asfint_object_t *)data, ddata); /* read the object and check its size value */ if (data->size < 50) { /* invalid size for data object */ ALOGI("ASF Data Object Size Error"); return ASF_ERROR_OBJECT_SIZE; } else if (data->type != GUID_DATA) { ALOGE("Data Object Not follow by Header Object"); return ASF_ERROR_INVALID_OBJECT; } } //seek to Header Object's data, and read header->data from iostream file->iostream.seek(iostream->source, 30); header->data = (uint8_t*)malloc(header->datalen * sizeof(uint8_t)); if (!header->data) { return ASF_ERROR_OUTOFMEM; } memset(header->data, 0, header->datalen * sizeof(uint8_t)); tmp = ASFByteIO::asf_byteio_read(header->data, header->datalen, iostream); if (tmp < 0) { ALOGE("asf_parse_header:error 3\n"); return tmp; } if (header->subobjects > 0) { uint64_t datalen; uint8_t *data = NULL; int i; ALOGV("starting to read subobjects\n"); /* use temporary variables for use during the read */ datalen = header->datalen; data = header->data; for (i=0; i<header->subobjects; i++) { void * tmp = NULL; asfint_object_t *current = NULL; if (datalen < 24) {//UUID+Size ==24 /* not enough data for reading object */ break; } //current = (asfint_object_t *)oscl_malloc(sizeof(asfint_object_t)); tmp = (void*)malloc(sizeof(asfint_object_t)); memset(tmp, 0, sizeof(asfint_object_t)); current = (asfint_object_t *)tmp; if (!current) { return ASF_ERROR_OUTOFMEM; } asf_parse_read_object(current, data); if (current->size > datalen || current->size < 24) { /* invalid object size */ ALOGE("invalid object size\n"); break; } /* Check if the current subobject is a header extension * object or just a normal subobject */ if (current->type == GUID_HEADER_EXTENSION && !header->ext) { int ret; asf_object_headerext_t *headerext = NULL; /* we handle header extension separately because it has * some subobjects as well */ //current = (asf_object_headerext_t*)oscl_realloc(current, sizeof(asf_object_headerext_t)); //headerext = (asf_object_headerext_t *) current; //changed by satish to fix compiler conversion problem tmp = (void*)realloc(tmp, sizeof(asf_object_headerext_t)); current = (asfint_object_t *)tmp; headerext = (asf_object_headerext_t *) tmp; headerext->first = NULL; headerext->last = NULL; ret = asf_parse_headerext(headerext, data, datalen); if (ret < 0) { /* error parsing header extension */ return ret; } header->ext = headerext; } else { if (current->type == GUID_HEADER_EXTENSION) { ALOGV("WARNING! Second header extension object found, ignoring it!\n"); } current->datalen = current->size - 24; current->data = data + 24; /* add to list of subobjects */ if (!header->first) { header->first = current; header->last = current; } else { header->last->next = current; header->last = current; } } data += current->size; datalen -= current->size; } if (i != header->subobjects || datalen != 0) { /* header data size doesn't match given subobject count */ return ASF_ERROR_INVALID_VALUE; } ALOGV("%d subobjects read successfully\n", i); } tmp = asf_parse_header_validate(file->header); if (tmp < 0) { /* header read ok but doesn't validate correctly */ return tmp; } ALOGV("header validated correctly\n"); return header->size; }