g_error bmp_load(hwrbitmap *hbmp, const u8 *data, u32 datalen) { struct bmp_fileheader *fhdr; struct bmp_infoheader *ihdr; int w,h,bpp; const u8 *rasterdata, *linebegin; g_error e; u32 offset, compression, numcolors, *u32p; int x,y,shift,mask,index; u8 byte; pgcolor c, c2, colortable[MAXPALETTE]; #ifdef CONFIG_DITHER hwrdither dither; #endif /* Load the headers. Fileheader is after "BM", infoheader is after that */ if (datalen < FILEHEADER_LEN + INFOHEADER_LEN) return mkerror(PG_ERRT_BADPARAM,41); /* Corrupt BMP header */ fhdr = (struct bmp_fileheader *) (data + 2); ihdr = (struct bmp_infoheader *) (data + FILEHEADER_LEN); /* Important header values */ w = LITTLE_LONG(ihdr->width); h = LITTLE_LONG(ihdr->height); bpp = LITTLE_SHORT(ihdr->bpp); compression = LITTLE_LONG(ihdr->compression); numcolors = LITTLE_LONG(ihdr->colors_used); offset = LITTLE_LONG(fhdr->data_offset); if(!numcolors) { numcolors=(offset-FILEHEADER_LEN-INFOHEADER_LEN)>>2; if(numcolors>1<<bpp) numcolors=1<<bpp; }
local int unzlocal_GetCurrentFileInfoInternal ( unzFile file, unz_file_info *pfile_info, unz_file_info_internal *pfile_info_internal, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize) { char buf[46]; unz_s* s; unz_file_info file_info; unz_file_info_internal file_info_internal = {0}; int err=UNZ_OK; uLong uMagic; long lSeek=0; if (file==NULL) return UNZ_PARAMERROR; s=(unz_s*)file; if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) err=UNZ_ERRNO; // UTTAR: Reducing the number of calls to fread drastically to improve loading performance if(fread(buf, 46, 1, s->file) != 1) { err = UNZ_ERRNO; memset(&file_info, 0, sizeof(file_info)); } else { uMagic = LITTLE_INT(*((int*)&buf[0])); file_info.version = LITTLE_SHORT(*((short*)&buf[4])); file_info.version_needed = LITTLE_SHORT(*((short*)&buf[6])); file_info.flag = LITTLE_SHORT(*((short*)&buf[8])); file_info.compression_method = LITTLE_SHORT(*((short*)&buf[10])); file_info.dosDate = LITTLE_INT(*((int*)&buf[12])); file_info.crc = LITTLE_INT(*((int*)&buf[16])); file_info.compressed_size = LITTLE_INT(*((int*)&buf[20])); file_info.uncompressed_size = LITTLE_INT(*((int*)&buf[24])); file_info.size_filename = LITTLE_SHORT(*((short*)&buf[28])); file_info.size_file_extra = LITTLE_SHORT(*((short*)&buf[30])); file_info.size_file_comment = LITTLE_SHORT(*((short*)&buf[32])); file_info.disk_num_start = LITTLE_SHORT(*((short*)&buf[34])); file_info.internal_fa = LITTLE_SHORT(*((short*)&buf[36])); file_info.external_fa = LITTLE_INT(*((int*)&buf[38])); file_info_internal.offset_curfile = LITTLE_INT(*((int*)&buf[42])); if (uMagic!=0x02014b50) err=UNZ_BADZIPFILE; unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); lSeek+=file_info.size_filename; } if ((err==UNZ_OK) && (szFileName!=NULL)) { uLong uSizeRead ; if (file_info.size_filename<fileNameBufferSize) { *(szFileName+file_info.size_filename)='\0'; uSizeRead = file_info.size_filename; } else uSizeRead = fileNameBufferSize; if ((file_info.size_filename>0) && (fileNameBufferSize>0)) if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1) err=UNZ_ERRNO; lSeek -= uSizeRead; } if ((err==UNZ_OK) && (extraField!=NULL)) { uLong uSizeRead ; if (file_info.size_file_extra<extraFieldBufferSize) uSizeRead = file_info.size_file_extra; else uSizeRead = extraFieldBufferSize; if (lSeek!=0) { if (fseek(s->file,lSeek,SEEK_CUR)==0) lSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1) err=UNZ_ERRNO; lSeek += file_info.size_file_extra - uSizeRead; } else lSeek+=file_info.size_file_extra; if ((err==UNZ_OK) && (szComment!=NULL)) { uLong uSizeRead ; if (file_info.size_file_comment<commentBufferSize) { *(szComment+file_info.size_file_comment)='\0'; uSizeRead = file_info.size_file_comment; } else uSizeRead = commentBufferSize; if (lSeek!=0) { if (fseek(s->file,lSeek,SEEK_CUR)==0) lSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_comment>0) && (commentBufferSize>0)) if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1) err=UNZ_ERRNO; lSeek+=file_info.size_file_comment - uSizeRead; } else lSeek+=file_info.size_file_comment; if ((err==UNZ_OK) && (pfile_info!=NULL)) *pfile_info=file_info; if(err == UNZ_ERRNO) return err; if (pfile_info_internal!=NULL) *pfile_info_internal=file_info_internal; return err; }
/* Open a Zip file. path contain the full pathname (by example, on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer "zlib/zlib109.zip". If the zipfile cannot be opened (file don't exist or in not valid), the return value is NULL. Else, the return value is a unzFile Handle, usable with other function of this unzip package. */ unzFile ZIP_Open (const char *path, unsigned char hash[MAX_HASH_SIZE], int *hashlen) { unz_s us; unz_s *s; uLong central_pos,uL; FILE * fin ; char buf[22]; char *lowercase_name; int i; uLong number_disk; /* number of the current dist, used for spaning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used for spaning ZIP, unsupported, always 0*/ uLong number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ int numFiles, err=UNZ_OK; fin=fopen(path,"rb"); if (fin==NULL) return NULL; central_pos = unzlocal_SearchCentralDir(fin); if (central_pos==0) err=UNZ_ERRNO; if (fseek(fin,central_pos,SEEK_SET)!=0) err=UNZ_ERRNO; // UTTAR: Reducing the number of calls to fread drastically to improve loading performance if(fread(buf, 22, 1, fin) != 1) { fclose(fin); return NULL; } else { uL = LITTLE_INT(*((int*)&buf[0])); number_disk = LITTLE_SHORT(*((short*)&buf[4])); number_disk_with_CD = LITTLE_SHORT(*((short*)&buf[6])); us.gi.number_entry = LITTLE_SHORT(*((short*)&buf[8])); number_entry_CD = LITTLE_SHORT(*((short*)&buf[10])); us.size_central_dir = LITTLE_INT(*((int*)&buf[12])); us.offset_central_dir = LITTLE_INT(*((int*)&buf[16])); us.gi.size_comment = LITTLE_SHORT(*((short*)&buf[20])); if ((number_entry_CD!=us.gi.number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=UNZ_BADZIPFILE; if ((central_pos<us.offset_central_dir+us.size_central_dir) && (err==UNZ_OK)) err=UNZ_BADZIPFILE; } if (err!=UNZ_OK) { fclose(fin); return NULL; } us.file=fin; us.byte_before_the_zipfile = central_pos - (us.offset_central_dir+us.size_central_dir); us.central_pos = central_pos; us.pfile_in_zip_read = NULL; s=(unz_s*)Tag_Malloc(sizeof(unz_s), MEM_ZIP); *s=us; err = unzGoToFirstFile((unzFile)s); Console_DPrintf("creating new filenameHash\n"); s->filenameHash = g_hash_table_new(g_str_hash, zip_str_equal); numFiles = 0; memset(hash, 0, MAX_HASH_SIZE); Hash_StartHash(); while (err == UNZ_OK) { char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; unzlocal_GetCurrentFileInfoInternal ((unzFile)s, &s->cur_file_info, &s->cur_file_info_internal, szCurrentFileName, sizeof(szCurrentFileName)-1, NULL, 0, NULL, 0); Hash_AddData((char *)&s->cur_file_info, sizeof(s->cur_file_info)); Hash_AddData((char *)&s->cur_file_info_internal, sizeof(s->cur_file_info_internal)); lowercase_name = g_ascii_strdown(szCurrentFileName, -1); //Console_DPrintf("hashing key %s (%u) with value %p\n", lowercase_name, g_str_hash(lowercase_name), GUINT_TO_POINTER(s->pos_in_central_dir)); g_hash_table_insert(s->filenameHash, lowercase_name, GUINT_TO_POINTER(s->pos_in_central_dir)); numFiles++; err = unzGoToNextFile((unzFile)s); } *hashlen = Hash_EndHash(hash); Console_DPrintf("s2z hash \"%s\" is: ", path); for(i = 0; i < *hashlen; i++) Console_DPrintf("%02x", hash[i]); Console_DPrintf("\n"); Console_DPrintf("Done reading zip file contents - %i files\n", numFiles); if (err != UNZ_END_OF_LIST_OF_FILE) Console_DPrintf("ZIP error: err was %i\n", err); return (unzFile)s; }
/* Read the local header of the current zipfile Check the coherency of the local header and info in the end of central directory about this file store in *piSizeVar the size of extra info in local header (filename and size of extra field data) */ local int unzlocal_CheckCurrentFileCoherencyHeader ( unz_s* s, uInt* piSizeVar, uLong *poffset_local_extrafield, uInt *psize_local_extrafield) { char buf[30]; uLong uMagic,uData,uFlags; uLong size_filename = 0; uLong size_extra_field; int err=UNZ_OK; *piSizeVar = 0; *poffset_local_extrafield = 0; *psize_local_extrafield = 0; if (fseek(s->file,s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile,SEEK_SET)!=0) return UNZ_ERRNO; // UTTAR: Reducing the number of calls to fread drastically to improve loading performance if(fread(buf, 30, 1, s->file) != 1) { size_extra_field = 0; size_extra_field = 0; err = UNZ_ERRNO; } else { uMagic = LITTLE_INT(*((int*)&buf[0])); uData = LITTLE_SHORT(*((short*)&buf[4])); uFlags = LITTLE_SHORT(*((short*)&buf[6])); uData = LITTLE_SHORT(*((short*)&buf[8])); if (uData!=s->cur_file_info.compression_method) err=UNZ_BADZIPFILE; uData = LITTLE_INT(*((int*)&buf[14])); // Skipped date/time (4 bytes) if ((uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) err=UNZ_BADZIPFILE; uData = LITTLE_INT(*((int*)&buf[18])); if ((uData!=s->cur_file_info.compressed_size) &&((uFlags & 8)==0)) err=UNZ_BADZIPFILE; uData = LITTLE_INT(*((int*)&buf[22])); if ((uData!=s->cur_file_info.uncompressed_size) &&((uFlags & 8)==0)) err=UNZ_BADZIPFILE; size_filename = LITTLE_SHORT(*((short*)&buf[26])); if ((size_filename!=s->cur_file_info.size_filename)) err=UNZ_BADZIPFILE; size_extra_field = LITTLE_SHORT(*((short*)&buf[28])); if (uMagic!=0x04034b50) err=UNZ_BADZIPFILE; } *piSizeVar += (uInt)size_filename; *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename; *psize_local_extrafield = (uInt)size_extra_field; *piSizeVar += (uInt)size_extra_field; return err; }