diff options
Diffstat (limited to 'contrib/extractor')
-rw-r--r-- | contrib/extractor/adt.cpp | 34 | ||||
-rw-r--r-- | contrib/extractor/libmpq/common.cpp | 1356 | ||||
-rw-r--r-- | contrib/extractor/libmpq/common.h | 42 | ||||
-rw-r--r-- | contrib/extractor/libmpq/explode.cpp | 656 | ||||
-rw-r--r-- | contrib/extractor/libmpq/explode.h | 90 | ||||
-rw-r--r-- | contrib/extractor/libmpq/extract.cpp | 332 | ||||
-rw-r--r-- | contrib/extractor/libmpq/huffman.cpp | 1498 | ||||
-rw-r--r-- | contrib/extractor/libmpq/huffman.h | 72 | ||||
-rw-r--r-- | contrib/extractor/libmpq/mpq.cpp | 970 | ||||
-rw-r--r-- | contrib/extractor/libmpq/mpq.h | 230 | ||||
-rw-r--r-- | contrib/extractor/libmpq/parser.cpp | 434 | ||||
-rw-r--r-- | contrib/extractor/libmpq/wave.cpp | 274 | ||||
-rw-r--r-- | contrib/extractor/libmpq/wave.h | 8 |
13 files changed, 2998 insertions, 2998 deletions
diff --git a/contrib/extractor/adt.cpp b/contrib/extractor/adt.cpp index dde87e5fc28..5cace2a70a5 100644 --- a/contrib/extractor/adt.cpp +++ b/contrib/extractor/adt.cpp @@ -84,7 +84,7 @@ bool LoadADT(char* filename) //if(fourcc == 0x4d4f4446) // MODF if(fourcc == 0x4d48324f) // MH2O new in WotLK { - // здесь надо запомнить базовую позицию в файле тк все смещения будут от него + // здес?надо запомнит?базову?позици??файл?тк вс?смещен? буду?от него uint32 base_pos = mf.getPos(); uint32 header_pos = 0; MH2O_offsData *LiqOffsData = new MH2O_offsData; @@ -94,24 +94,24 @@ bool LoadADT(char* filename) { mf.read(LiqOffsData, 0x0C); header_pos = mf.getPos(); - if(LiqOffsData->offsData1 != 0) // если данные в Data1 о воде есть, то их надо конвертировать + if(LiqOffsData->offsData1 != 0) // если данные ?Data1 ?воде есть, то их надо конвертировать { - // переходим по смещению из offsData1 ОТ НАЧАЛА куска + // перехоим по смещению из offsData1 ОТ НАЧАЛА куск? mf.seek(base_pos + LiqOffsData->offsData1); - mf.read(LiqChunkData1, 0x18); // считываем сами данные в структуру типа MH2O_Data1 - // заносим данные флага для куска + mf.read(LiqChunkData1, 0x18); // считывае?сами данные ?структур?типа MH2O_Data1 + // заноси?данные флаг?для куск? if(LiqType[LiqChunkData1->LiquidTypeId] == 0xffff) printf("\nCan't find Liquid type for map %s\nchunk %d\n", filename, chunk_num); else if(LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_WATER || LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_OCEAN) MapLiqFlag[chunk_num] |= 1; // water/ocean else if(LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_MAGMA || LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_SLIME) MapLiqFlag[chunk_num] |= 2; // magma/slime - // предварительно заполняем весь кусок данными - нет воды + // предварительно заполняем весь кусо?данным?- не?воды for(int j = 0; j < 81; ++j) { ChunkLiqHeight[j] = -999999; // no liquid/water } - // теперь вычисляем те что с водой и перезаписываем их в куске + // теперь вычисляем те чт??водо??перезаписываем их ?куск? for(int b = 0; b <= LiqChunkData1->height; ++b) { for(int c = LiqChunkData1->xOffset; c <= (LiqChunkData1->xOffset + LiqChunkData1->width); ++c) @@ -120,22 +120,22 @@ bool LoadADT(char* filename) ChunkLiqHeight[n] = LiqChunkData1->heightLevel1; } } - mf.seek(header_pos); // и не забыть вернуться на исходную позицию именно В ХИДЕРЕ + mf.seek(header_pos); // ?не забыть вернуться на исходную позици?именно ?ХИДЕРЕ } - else // если данных в Data1 нет, то надо заполнить весь кусок, но данными - нет воды + else // если данных ?Data1 не? то надо заполнит?весь кусо? но данным?- не?воды { for(int j = 0; j < 81; ++j) ChunkLiqHeight[j] = -999999; // no liquid/water } if(!(chunk_num % 16)) - m = 1024 * (chunk_num / 16); // смещение по рядам кусков с перекрытием = 1024 - k = m + (chunk_num % 16) * 8; // устанавливаемся на начальный индекс для заполнения ряда - // заносим данные куска в массив для карты, с перекрытием и обрезанием кусков тк данных 81 - // это аналог старого обрезания граничных правых-боковых и нижних данных - for(int p = 0; p < 72; p += 9) // нижние 8 не заносим тк они дублируется след куском + m = 1024 * (chunk_num / 16); // смещение по ?да?кусков ?перекрытие?= 1024 + k = m + (chunk_num % 16) * 8; // устанавливаемся на начальны?индекс для заполнен? ?да + // заноси?данные куск??массив для карт? ?перекрытие??обрезанием кусков тк данных 81 + // эт?аналог старог?обрезания граничны?правых-боковы??нижних данных + for(int p = 0; p < 72; p += 9) // нижние 8 не заноси?тк он?дублируется след куском { - for(int s = 0; s < 8; ++s) // 9 значение в строке не заносим тк оно дублируется след куском, а в правых-боковых обрезается для 128х128 + for(int s = 0; s < 8; ++s) // 9 значение ?строке не заноси?тк он?дублируется след куском, ??правых-боковы?обрезает? для 128?28 { MapLiqHeight[k] = ChunkLiqHeight[p + s]; ++k; @@ -244,7 +244,7 @@ inline void LoadMapChunk(MPQFile &mf, chunk *_chunk) { nextpos = mf.getPos() + 0x1C0; // size fix } - else if(fourcc == 0x4d434c51) // не будем учитывать если уже были данные в MH2O, перестраховка :) // MCLQ + else if(fourcc == 0x4d434c51) // не буде?учитыват?если уж?были данные ?MH2O, перестраховк?:) // MCLQ { // liquid / water level char fcc1[5]; @@ -280,7 +280,7 @@ inline void LoadMapChunk(MPQFile &mf, chunk *_chunk) if(chunkflags & 16) MapLiqFlag[chunk_num] |= 2; // magma/slime } - // заполнем так же как в MH2O + // заполнем та?же ка??MH2O if(!(chunk_num % 16)) m = 1024 * (chunk_num / 16); k = m + (chunk_num % 16) * 8; diff --git a/contrib/extractor/libmpq/common.cpp b/contrib/extractor/libmpq/common.cpp index 7b902087540..7376a500870 100644 --- a/contrib/extractor/libmpq/common.cpp +++ b/contrib/extractor/libmpq/common.cpp @@ -34,19 +34,19 @@ * This function decrypts a MPQ block. */ int libmpq_decrypt_block(mpq_archive *mpq_a, unsigned int *block, unsigned int length, unsigned int seed1) { - unsigned int seed2 = 0xEEEEEEEE; - unsigned int ch; - - /* Round to unsigned int's */ - length >>= 2; - while (length-- > 0) { - seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; - ch = *block ^ (seed1 + seed2); - seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); - seed2 = ch + seed2 + (seed2 << 5) + 3; - *block++ = ch; - } - return LIBMPQ_TOOLS_SUCCESS; + unsigned int seed2 = 0xEEEEEEEE; + unsigned int ch; + + /* Round to unsigned int's */ + length >>= 2; + while (length-- > 0) { + seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; + ch = *block ^ (seed1 + seed2); + seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); + seed2 = ch + seed2 + (seed2 << 5) + 3; + *block++ = ch; + } + return LIBMPQ_TOOLS_SUCCESS; } /* @@ -54,164 +54,164 @@ int libmpq_decrypt_block(mpq_archive *mpq_a, unsigned int *block, unsigned int l * file informations. */ int libmpq_decrypt_hashtable(mpq_archive *mpq_a, unsigned char *pbKey) { - unsigned int seed1 = 0x7FED7FED; - unsigned int seed2 = 0xEEEEEEEE; - unsigned int ch; /* One key character */ - unsigned int *pdwTable = (unsigned int *)(mpq_a->hashtable); - unsigned int length = mpq_a->header->hashtablesize * 4; - - /* Prepare seeds */ - while (*pbKey != 0) { - ch = toupper(*pbKey++); - seed1 = mpq_a->buf[0x300 + ch] ^ (seed1 + seed2); - seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; - } - - /* Decrypt it */ - seed2 = 0xEEEEEEEE; - while (length-- > 0) { - seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; - ch = *pdwTable ^ (seed1 + seed2); - seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); - seed2 = ch + seed2 + (seed2 << 5) + 3; - *pdwTable++ = ch; - } - return LIBMPQ_TOOLS_SUCCESS; + unsigned int seed1 = 0x7FED7FED; + unsigned int seed2 = 0xEEEEEEEE; + unsigned int ch; /* One key character */ + unsigned int *pdwTable = (unsigned int *)(mpq_a->hashtable); + unsigned int length = mpq_a->header->hashtablesize * 4; + + /* Prepare seeds */ + while (*pbKey != 0) { + ch = toupper(*pbKey++); + seed1 = mpq_a->buf[0x300 + ch] ^ (seed1 + seed2); + seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; + } + + /* Decrypt it */ + seed2 = 0xEEEEEEEE; + while (length-- > 0) { + seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; + ch = *pdwTable ^ (seed1 + seed2); + seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); + seed2 = ch + seed2 + (seed2 << 5) + 3; + *pdwTable++ = ch; + } + return LIBMPQ_TOOLS_SUCCESS; } /* * This function decrypts the blocktable. */ int libmpq_decrypt_blocktable(mpq_archive *mpq_a, unsigned char *pbKey) { - unsigned int seed1 = 0x7FED7FED; - unsigned int seed2 = 0xEEEEEEEE; - unsigned int ch; /* One key character */ - unsigned int *pdwTable = (unsigned int *)(mpq_a->blocktable); - unsigned int length = mpq_a->header->blocktablesize * 4; - - /* Prepare seeds */ - while(*pbKey != 0) { - ch = toupper(*pbKey++); - seed1 = mpq_a->buf[0x300 + ch] ^ (seed1 + seed2); - seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; - } - - /* Decrypt it */ - seed2 = 0xEEEEEEEE; - while(length-- > 0) { - seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; - ch = *pdwTable ^ (seed1 + seed2); - seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); - seed2 = ch + seed2 + (seed2 << 5) + 3; - *pdwTable++ = ch; - } - return LIBMPQ_TOOLS_SUCCESS; + unsigned int seed1 = 0x7FED7FED; + unsigned int seed2 = 0xEEEEEEEE; + unsigned int ch; /* One key character */ + unsigned int *pdwTable = (unsigned int *)(mpq_a->blocktable); + unsigned int length = mpq_a->header->blocktablesize * 4; + + /* Prepare seeds */ + while(*pbKey != 0) { + ch = toupper(*pbKey++); + seed1 = mpq_a->buf[0x300 + ch] ^ (seed1 + seed2); + seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; + } + + /* Decrypt it */ + seed2 = 0xEEEEEEEE; + while(length-- > 0) { + seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; + ch = *pdwTable ^ (seed1 + seed2); + seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); + seed2 = ch + seed2 + (seed2 << 5) + 3; + *pdwTable++ = ch; + } + return LIBMPQ_TOOLS_SUCCESS; } int libmpq_read_listfile(mpq_archive *mpq_a, FILE *fp) { - int mpq_size; - int mpq_ht_size; - int mpq_bt_size; - int mpq_blocksize; - int mpq_files; - int mpq_csize; - int mpq_fsize; - int entries; - char listdb_version[10]; - char libmpq_version[10]; - int listdb_temp_version = 0; - int libmpq_temp_version = 0; - - /* first check header and version */ - if (libmpq_conf_get_value(fp, "LIBMPQ_VERSION", mpq_a->mpq_l->mpq_version, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_version))) { - return LIBMPQ_CONF_EFILE_CORRUPT; - } else { - - /* copy to temp buffer for removing . characters */ - sprintf(listdb_version, (char *)mpq_a->mpq_l->mpq_version); - - /* remove . characters from listfile version */ - libmpq_conf_delete_char(listdb_version, "."); - - /* get libmpq version */ - sprintf(libmpq_version, "%i%i%i",LIBMPQ_MAJOR_VERSION, LIBMPQ_MINOR_VERSION, LIBMPQ_PATCH_VERSION); - - /* convert to number */ - listdb_temp_version = atoi(listdb_version); - libmpq_temp_version = atoi(libmpq_version); - - /* check if installed libmpq version is valid for listfile version */ - if ((libmpq_temp_version < listdb_temp_version) || (libmpq_temp_version == 0) || (listdb_temp_version == 0)) { - return LIBMPQ_CONF_EFILE_VERSION; - } - } - - /* check listfile header, the following entries must be set */ - if (libmpq_conf_get_value(fp, "MPQ_SIZE", &mpq_size, LIBMPQ_CONF_TYPE_INT, 0)) { - return LIBMPQ_CONF_EFILE_CORRUPT; - } - if (libmpq_conf_get_value(fp, "MPQ_HASHTABLE_SIZE", &mpq_ht_size, LIBMPQ_CONF_TYPE_INT, 0)) { - return LIBMPQ_CONF_EFILE_CORRUPT; - } - if (libmpq_conf_get_value(fp, "MPQ_BLOCKTABLE_SIZE", &mpq_bt_size, LIBMPQ_CONF_TYPE_INT, 0)) { - return LIBMPQ_CONF_EFILE_CORRUPT; - } - if (libmpq_conf_get_value(fp, "MPQ_BLOCKSIZE", &mpq_blocksize, LIBMPQ_CONF_TYPE_INT, 0)) { - return LIBMPQ_CONF_EFILE_CORRUPT; - } - if (libmpq_conf_get_value(fp, "MPQ_FILES", &mpq_files, LIBMPQ_CONF_TYPE_INT, 0)) { - return LIBMPQ_CONF_EFILE_CORRUPT; - } - if (libmpq_conf_get_value(fp, "MPQ_COMPRESSED_SIZE", &mpq_csize, LIBMPQ_CONF_TYPE_INT, 0)) { - return LIBMPQ_CONF_EFILE_CORRUPT; - } - if (libmpq_conf_get_value(fp, "MPQ_UNCOMPRESSED_SIZE", &mpq_fsize, LIBMPQ_CONF_TYPE_INT, 0)) { - return LIBMPQ_CONF_EFILE_CORRUPT; - } - if (libmpq_conf_get_value(fp, "MPQ_NAME", mpq_a->mpq_l->mpq_name, LIBMPQ_CONF_TYPE_CHAR, PATH_MAX)) { - return LIBMPQ_CONF_EFILE_CORRUPT; - } - if (libmpq_conf_get_value(fp, "MPQ_TYPE", mpq_a->mpq_l->mpq_type, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_type))) { - return LIBMPQ_CONF_EFILE_CORRUPT; - } - - /* these are optional parameters, if they are empty we set the struct members empty */ - libmpq_conf_get_value(fp, "MPQ_GAME", mpq_a->mpq_l->mpq_game, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_game)); - libmpq_conf_get_value(fp, "MPQ_GAME_VERSION", mpq_a->mpq_l->mpq_game_version, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_game_version)); - - /* check if we found a valid listfile for the given archive */ - if (mpq_a->header->hashtablesize == mpq_ht_size && mpq_a->header->blocktablesize == mpq_bt_size && mpq_a->blocksize == mpq_blocksize && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_ARCHIVE_SIZE) == mpq_size && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) == mpq_files && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_COMPRESSED_SIZE) == mpq_csize && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_UNCOMPRESSED_SIZE) == mpq_fsize) { - - /* check if the filelist is correct */ - if (!libmpq_conf_get_array(fp, "FILE_NAMES", (char ***)&mpq_a->mpq_l->mpq_files, &entries)) { - - /* we have a corrupt filelist, so return */ - return LIBMPQ_CONF_EFILE_LIST_CORRUPT; - } else { - - /* now check if filelist entries matches number of files in the archive. */ - if (entries != libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES)) { - libmpq_free_listfile((char **)mpq_a->mpq_l->mpq_files); - mpq_a->mpq_l->mpq_files = NULL; - return LIBMPQ_CONF_EFILE_LIST_CORRUPT; - } - } - } - - return LIBMPQ_TOOLS_SUCCESS; + int mpq_size; + int mpq_ht_size; + int mpq_bt_size; + int mpq_blocksize; + int mpq_files; + int mpq_csize; + int mpq_fsize; + int entries; + char listdb_version[10]; + char libmpq_version[10]; + int listdb_temp_version = 0; + int libmpq_temp_version = 0; + + /* first check header and version */ + if (libmpq_conf_get_value(fp, "LIBMPQ_VERSION", mpq_a->mpq_l->mpq_version, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_version))) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } else { + + /* copy to temp buffer for removing . characters */ + sprintf(listdb_version, (char *)mpq_a->mpq_l->mpq_version); + + /* remove . characters from listfile version */ + libmpq_conf_delete_char(listdb_version, "."); + + /* get libmpq version */ + sprintf(libmpq_version, "%i%i%i",LIBMPQ_MAJOR_VERSION, LIBMPQ_MINOR_VERSION, LIBMPQ_PATCH_VERSION); + + /* convert to number */ + listdb_temp_version = atoi(listdb_version); + libmpq_temp_version = atoi(libmpq_version); + + /* check if installed libmpq version is valid for listfile version */ + if ((libmpq_temp_version < listdb_temp_version) || (libmpq_temp_version == 0) || (listdb_temp_version == 0)) { + return LIBMPQ_CONF_EFILE_VERSION; + } + } + + /* check listfile header, the following entries must be set */ + if (libmpq_conf_get_value(fp, "MPQ_SIZE", &mpq_size, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_HASHTABLE_SIZE", &mpq_ht_size, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_BLOCKTABLE_SIZE", &mpq_bt_size, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_BLOCKSIZE", &mpq_blocksize, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_FILES", &mpq_files, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_COMPRESSED_SIZE", &mpq_csize, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_UNCOMPRESSED_SIZE", &mpq_fsize, LIBMPQ_CONF_TYPE_INT, 0)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_NAME", mpq_a->mpq_l->mpq_name, LIBMPQ_CONF_TYPE_CHAR, PATH_MAX)) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + if (libmpq_conf_get_value(fp, "MPQ_TYPE", mpq_a->mpq_l->mpq_type, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_type))) { + return LIBMPQ_CONF_EFILE_CORRUPT; + } + + /* these are optional parameters, if they are empty we set the struct members empty */ + libmpq_conf_get_value(fp, "MPQ_GAME", mpq_a->mpq_l->mpq_game, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_game)); + libmpq_conf_get_value(fp, "MPQ_GAME_VERSION", mpq_a->mpq_l->mpq_game_version, LIBMPQ_CONF_TYPE_CHAR, sizeof(mpq_a->mpq_l->mpq_game_version)); + + /* check if we found a valid listfile for the given archive */ + if (mpq_a->header->hashtablesize == mpq_ht_size && mpq_a->header->blocktablesize == mpq_bt_size && mpq_a->blocksize == mpq_blocksize && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_ARCHIVE_SIZE) == mpq_size && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) == mpq_files && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_COMPRESSED_SIZE) == mpq_csize && libmpq_archive_info(mpq_a, LIBMPQ_MPQ_UNCOMPRESSED_SIZE) == mpq_fsize) { + + /* check if the filelist is correct */ + if (!libmpq_conf_get_array(fp, "FILE_NAMES", (char ***)&mpq_a->mpq_l->mpq_files, &entries)) { + + /* we have a corrupt filelist, so return */ + return LIBMPQ_CONF_EFILE_LIST_CORRUPT; + } else { + + /* now check if filelist entries matches number of files in the archive. */ + if (entries != libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES)) { + libmpq_free_listfile((char **)mpq_a->mpq_l->mpq_files); + mpq_a->mpq_l->mpq_files = NULL; + return LIBMPQ_CONF_EFILE_LIST_CORRUPT; + } + } + } + + return LIBMPQ_TOOLS_SUCCESS; } /* * This function frees up the space reserved by libmpq_get_listfile() */ int libmpq_free_listfile(char **filelist) { - int i = 0; - while (filelist[i]) { - free(filelist[i++]); - } - free(filelist); + int i = 0; + while (filelist[i]) { + free(filelist[i++]); + } + free(filelist); - return LIBMPQ_TOOLS_SUCCESS; + return LIBMPQ_TOOLS_SUCCESS; } /* @@ -220,84 +220,84 @@ int libmpq_free_listfile(char **filelist) { * array. */ /*int libmpq_detect_listfile_rec(char path[PATH_MAX], char ***filelist, int *fl_count, int *fl_size) { - char nextpath[PATH_MAX]; - DIR *dp = opendir(path); - FILE *fp; - struct dirent *entry; - struct stat statbuf; - char buf[LIBMPQ_CONF_BUFSIZE]; - - if (dp == NULL) { - return LIBMPQ_CONF_EOPEN_DIR; - } else { - while ((entry = readdir(dp)) != NULL) { - if (strncmp(entry->d_name, ".", 1) == 0 || strncmp(entry->d_name, "..", 2) == 0) { - continue; - } - if (strnlen(path, PATH_MAX) + strnlen(entry->d_name, PATH_MAX) + 2 > sizeof nextpath) { - continue; - } - - snprintf(nextpath, PATH_MAX, "%s/%s", path, entry->d_name); - - // check if file extension matches listdb file extension - if (strncmp(&entry->d_name[strlen(entry->d_name) - strlen(LIBMPQ_CONF_EXT)], LIBMPQ_CONF_EXT, strlen(LIBMPQ_CONF_EXT)) == 0) { - - // check if it is really a listdb file - if ((fp = fopen(nextpath, "r")) != NULL ) { - while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) { - char *line; - - buf[strlen(buf) - 1] = '\0'; - - // skip whitespace - for (line = buf; isspace(*line); line++) { - continue; - } - - // skip empty line - if (line[0] == '\0') { - continue; - } - - // skip comments - if (line[0] == '#') { - continue; - } - - //search for listdb header; dirty but works :) - if (!strncasecmp(line, LIBMPQ_CONF_HEADER, strlen(LIBMPQ_CONF_HEADER))) { - - // set the next filelist entry to a copy of the file path - (*filelist)[(*fl_count)++] = strdup(nextpath); - - // increase the array size - if ((*fl_count) == (*fl_size)) { - (*filelist) = realloc((*filelist), ((*fl_size) + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *)); - (*fl_size) += LIBMPQ_CONF_FL_INCREMENT; - } - - // header found so we could stop reading the file. - break; - } - } - fclose(fp); - } - } - - if (stat(nextpath, &statbuf) < 0) { - continue; - } - - // if entry ia a subdirectory, read it - if (S_ISDIR(statbuf.st_mode)) { - libmpq_detect_listfile_rec(nextpath, filelist, fl_count, fl_size); - } - } - closedir(dp); - } - - return LIBMPQ_TOOLS_SUCCESS; + char nextpath[PATH_MAX]; + DIR *dp = opendir(path); + FILE *fp; + struct dirent *entry; + struct stat statbuf; + char buf[LIBMPQ_CONF_BUFSIZE]; + + if (dp == NULL) { + return LIBMPQ_CONF_EOPEN_DIR; + } else { + while ((entry = readdir(dp)) != NULL) { + if (strncmp(entry->d_name, ".", 1) == 0 || strncmp(entry->d_name, "..", 2) == 0) { + continue; + } + if (strnlen(path, PATH_MAX) + strnlen(entry->d_name, PATH_MAX) + 2 > sizeof nextpath) { + continue; + } + + snprintf(nextpath, PATH_MAX, "%s/%s", path, entry->d_name); + + // check if file extension matches listdb file extension + if (strncmp(&entry->d_name[strlen(entry->d_name) - strlen(LIBMPQ_CONF_EXT)], LIBMPQ_CONF_EXT, strlen(LIBMPQ_CONF_EXT)) == 0) { + + // check if it is really a listdb file + if ((fp = fopen(nextpath, "r")) != NULL ) { + while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) { + char *line; + + buf[strlen(buf) - 1] = '\0'; + + // skip whitespace + for (line = buf; isspace(*line); line++) { + continue; + } + + // skip empty line + if (line[0] == '\0') { + continue; + } + + // skip comments + if (line[0] == '#') { + continue; + } + + //search for listdb header; dirty but works :) + if (!strncasecmp(line, LIBMPQ_CONF_HEADER, strlen(LIBMPQ_CONF_HEADER))) { + + // set the next filelist entry to a copy of the file path + (*filelist)[(*fl_count)++] = strdup(nextpath); + + // increase the array size + if ((*fl_count) == (*fl_size)) { + (*filelist) = realloc((*filelist), ((*fl_size) + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *)); + (*fl_size) += LIBMPQ_CONF_FL_INCREMENT; + } + + // header found so we could stop reading the file. + break; + } + } + fclose(fp); + } + } + + if (stat(nextpath, &statbuf) < 0) { + continue; + } + + // if entry ia a subdirectory, read it + if (S_ISDIR(statbuf.st_mode)) { + libmpq_detect_listfile_rec(nextpath, filelist, fl_count, fl_size); + } + } + closedir(dp); + } + + return LIBMPQ_TOOLS_SUCCESS; } */ @@ -309,69 +309,69 @@ int libmpq_free_listfile(char **filelist) { * we can find the decryption key. */ int libmpq_detect_fileseed(mpq_archive *mpq_a, unsigned int *block, unsigned int decrypted) { - unsigned int saveseed1; - unsigned int temp = *block ^ decrypted; /* temp = seed1 + seed2 */ - int i = 0; - temp -= 0xEEEEEEEE; /* temp = seed1 + mpq_a->buf[0x400 + (seed1 & 0xFF)] */ - - for (i = 0; i < 0x100; i++) { /* Try all 255 possibilities */ - unsigned int seed1; - unsigned int seed2 = 0xEEEEEEEE; - unsigned int ch; - - /* Try the first unsigned int's (We exactly know the value) */ - seed1 = temp - mpq_a->buf[0x400 + i]; - seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; - ch = block[0] ^ (seed1 + seed2); - - if (ch != decrypted) { - continue; - } - - /* Add 1 because we are decrypting block positions */ - saveseed1 = seed1 + 1; - - /* - * If OK, continue and test the second value. We don't know exactly the value, - * but we know that the second one has lower 16 bits set to zero - * (no compressed block is larger than 0xFFFF bytes) - */ - seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); - seed2 = ch + seed2 + (seed2 << 5) + 3; - seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; - ch = block[1] ^ (seed1 + seed2); - if ((ch & 0xFFFF0000) == 0) { - return saveseed1; - } - } - return LIBMPQ_TOOLS_SUCCESS; + unsigned int saveseed1; + unsigned int temp = *block ^ decrypted; /* temp = seed1 + seed2 */ + int i = 0; + temp -= 0xEEEEEEEE; /* temp = seed1 + mpq_a->buf[0x400 + (seed1 & 0xFF)] */ + + for (i = 0; i < 0x100; i++) { /* Try all 255 possibilities */ + unsigned int seed1; + unsigned int seed2 = 0xEEEEEEEE; + unsigned int ch; + + /* Try the first unsigned int's (We exactly know the value) */ + seed1 = temp - mpq_a->buf[0x400 + i]; + seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; + ch = block[0] ^ (seed1 + seed2); + + if (ch != decrypted) { + continue; + } + + /* Add 1 because we are decrypting block positions */ + saveseed1 = seed1 + 1; + + /* + * If OK, continue and test the second value. We don't know exactly the value, + * but we know that the second one has lower 16 bits set to zero + * (no compressed block is larger than 0xFFFF bytes) + */ + seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B); + seed2 = ch + seed2 + (seed2 << 5) + 3; + seed2 += mpq_a->buf[0x400 + (seed1 & 0xFF)]; + ch = block[1] ^ (seed1 + seed2); + if ((ch & 0xFFFF0000) == 0) { + return saveseed1; + } + } + return LIBMPQ_TOOLS_SUCCESS; } /* * This function initialize the decryption buffer */ int libmpq_init_buffer(mpq_archive *mpq_a) { - unsigned int seed = 0x00100001; - unsigned int index1 = 0; - unsigned int index2 = 0; - int i; - - memset(mpq_a->buf, 0, sizeof(mpq_a->buf)); - - /* Initialize the decryption buffer. */ - for (index1 = 0; index1 < 0x100; index1++) { - for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100) { - unsigned int temp1, temp2; - seed = (seed * 125 + 3) % 0x2AAAAB; - temp1 = (seed & 0xFFFF) << 0x10; - - seed = (seed * 125 + 3) % 0x2AAAAB; - temp2 = (seed & 0xFFFF); - - mpq_a->buf[index2] = (temp1 | temp2); - } - } - return LIBMPQ_TOOLS_SUCCESS; + unsigned int seed = 0x00100001; + unsigned int index1 = 0; + unsigned int index2 = 0; + int i; + + memset(mpq_a->buf, 0, sizeof(mpq_a->buf)); + + /* Initialize the decryption buffer. */ + for (index1 = 0; index1 < 0x100; index1++) { + for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100) { + unsigned int temp1, temp2; + seed = (seed * 125 + 3) % 0x2AAAAB; + temp1 = (seed & 0xFFFF) << 0x10; + + seed = (seed * 125 + 3) % 0x2AAAAB; + temp2 = (seed & 0xFFFF); + + mpq_a->buf[index2] = (temp1 | temp2); + } + } + return LIBMPQ_TOOLS_SUCCESS; } /* @@ -380,52 +380,52 @@ int libmpq_init_buffer(mpq_archive *mpq_a) { * be decrypted for later use. */ int libmpq_read_hashtable(mpq_archive *mpq_a) { - unsigned int bytes = 0; - int rb = 0; - - /* - * Allocate memory. Note that the block table should be as large as the - * hash table. (for later file additions) - */ - mpq_a->hashtable = (mpq_hash *)malloc(sizeof(mpq_hash) * mpq_a->header->hashtablesize); - - if (!mpq_a->hashtable) { - return LIBMPQ_EALLOCMEM; - } - - /* Read the hash table into the buffer */ - bytes = mpq_a->header->hashtablesize * sizeof(mpq_hash); - - #ifdef WIN32 - _lseeki64(mpq_a->fd, mpq_a->header->hashtablepos, SEEK_SET); - #else - lseek64(mpq_a->fd, mpq_a->header->hashtablepos, SEEK_SET); - #endif - - rb = _read(mpq_a->fd, mpq_a->hashtable, bytes); - if (rb != bytes) { - return LIBMPQ_EFILE_CORRUPT; - } - - /* Decrypt hash table and check if it is correctly decrypted */ - mpq_hash *mpq_h_end = mpq_a->hashtable + mpq_a->header->hashtablesize; - mpq_hash *mpq_h = NULL; - - libmpq_decrypt_hashtable(mpq_a, (unsigned char *)"(hash table)"); - - /* Check hash table if is correctly decrypted */ - for (mpq_h = mpq_a->hashtable; mpq_h < mpq_h_end; mpq_h++) { - if (mpq_h->locale != 0xFFFFFFFF && (mpq_h->locale & 0xFFFF0000) != 0) { - return LIBMPQ_EFILE_FORMAT; - } - - /* Remember the highest block table entry */ - if (mpq_h->blockindex < LIBMPQ_HASH_ENTRY_DELETED && mpq_h->blockindex > 0) { - mpq_a->maxblockindex = mpq_h->blockindex; - } - } - - return LIBMPQ_TOOLS_SUCCESS; + unsigned int bytes = 0; + int rb = 0; + + /* + * Allocate memory. Note that the block table should be as large as the + * hash table. (for later file additions) + */ + mpq_a->hashtable = (mpq_hash *)malloc(sizeof(mpq_hash) * mpq_a->header->hashtablesize); + + if (!mpq_a->hashtable) { + return LIBMPQ_EALLOCMEM; + } + + /* Read the hash table into the buffer */ + bytes = mpq_a->header->hashtablesize * sizeof(mpq_hash); + + #ifdef WIN32 + _lseeki64(mpq_a->fd, mpq_a->header->hashtablepos, SEEK_SET); + #else + lseek64(mpq_a->fd, mpq_a->header->hashtablepos, SEEK_SET); + #endif + + rb = _read(mpq_a->fd, mpq_a->hashtable, bytes); + if (rb != bytes) { + return LIBMPQ_EFILE_CORRUPT; + } + + /* Decrypt hash table and check if it is correctly decrypted */ + mpq_hash *mpq_h_end = mpq_a->hashtable + mpq_a->header->hashtablesize; + mpq_hash *mpq_h = NULL; + + libmpq_decrypt_hashtable(mpq_a, (unsigned char *)"(hash table)"); + + /* Check hash table if is correctly decrypted */ + for (mpq_h = mpq_a->hashtable; mpq_h < mpq_h_end; mpq_h++) { + if (mpq_h->locale != 0xFFFFFFFF && (mpq_h->locale & 0xFFFF0000) != 0) { + return LIBMPQ_EFILE_FORMAT; + } + + /* Remember the highest block table entry */ + if (mpq_h->blockindex < LIBMPQ_HASH_ENTRY_DELETED && mpq_h->blockindex > 0) { + mpq_a->maxblockindex = mpq_h->blockindex; + } + } + + return LIBMPQ_TOOLS_SUCCESS; } /* @@ -437,365 +437,365 @@ int libmpq_read_hashtable(mpq_archive *mpq_a) { * cracked Diablo versions. */ int libmpq_read_blocktable(mpq_archive *mpq_a) { - unsigned int bytes = 0; - int rb = 0; - - /* - * Allocate memory. Note that the block table should be as large as the - * hash table. (for later file additions) - */ - mpq_a->blocktable = (mpq_block *)malloc(sizeof(mpq_block) * mpq_a->header->hashtablesize); - mpq_a->blockbuf = (unsigned char *)malloc(mpq_a->blocksize); - - if (!mpq_a->blocktable || !mpq_a->blockbuf) { - return LIBMPQ_EALLOCMEM; - } - - /* Read the block table into the buffer */ - bytes = mpq_a->header->blocktablesize * sizeof(mpq_block); - memset(mpq_a->blocktable, 0, mpq_a->header->blocktablesize * sizeof(mpq_block)); - - #ifdef WIN32 - _lseeki64(mpq_a->fd, mpq_a->header->blocktablepos, SEEK_SET); - #else - lseek64(mpq_a->fd, mpq_a->header->blocktablepos, SEEK_SET); - #endif - - rb = _read(mpq_a->fd, mpq_a->blocktable, bytes); - if (rb != bytes) { - return LIBMPQ_EFILE_CORRUPT; - } - - /* - * Decrypt block table. Some MPQs don't have encrypted block table, - * e.g. cracked Diablo version. We have to check if block table is - * already decrypted - */ - mpq_block *mpq_b_end = mpq_a->blocktable + mpq_a->maxblockindex + 1; - mpq_block *mpq_b = NULL; - unsigned int archivesize = mpq_a->header->archivesize + mpq_a->mpqpos; - - if (mpq_a->header->offset != mpq_a->blocktable->filepos) { - libmpq_decrypt_blocktable(mpq_a, (unsigned char *)"(block table)"); - } - for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { - if (mpq_b->filepos > archivesize || mpq_b->csize > archivesize) { - if ((mpq_a->flags & LIBMPQ_FLAG_PROTECTED) == 0) { - return LIBMPQ_EFILE_FORMAT; - } - } - mpq_b->filepos += mpq_a->mpqpos; - } - - return LIBMPQ_TOOLS_SUCCESS; + unsigned int bytes = 0; + int rb = 0; + + /* + * Allocate memory. Note that the block table should be as large as the + * hash table. (for later file additions) + */ + mpq_a->blocktable = (mpq_block *)malloc(sizeof(mpq_block) * mpq_a->header->hashtablesize); + mpq_a->blockbuf = (unsigned char *)malloc(mpq_a->blocksize); + + if (!mpq_a->blocktable || !mpq_a->blockbuf) { + return LIBMPQ_EALLOCMEM; + } + + /* Read the block table into the buffer */ + bytes = mpq_a->header->blocktablesize * sizeof(mpq_block); + memset(mpq_a->blocktable, 0, mpq_a->header->blocktablesize * sizeof(mpq_block)); + + #ifdef WIN32 + _lseeki64(mpq_a->fd, mpq_a->header->blocktablepos, SEEK_SET); + #else + lseek64(mpq_a->fd, mpq_a->header->blocktablepos, SEEK_SET); + #endif + + rb = _read(mpq_a->fd, mpq_a->blocktable, bytes); + if (rb != bytes) { + return LIBMPQ_EFILE_CORRUPT; + } + + /* + * Decrypt block table. Some MPQs don't have encrypted block table, + * e.g. cracked Diablo version. We have to check if block table is + * already decrypted + */ + mpq_block *mpq_b_end = mpq_a->blocktable + mpq_a->maxblockindex + 1; + mpq_block *mpq_b = NULL; + unsigned int archivesize = mpq_a->header->archivesize + mpq_a->mpqpos; + + if (mpq_a->header->offset != mpq_a->blocktable->filepos) { + libmpq_decrypt_blocktable(mpq_a, (unsigned char *)"(block table)"); + } + for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { + if (mpq_b->filepos > archivesize || mpq_b->csize > archivesize) { + if ((mpq_a->flags & LIBMPQ_FLAG_PROTECTED) == 0) { + return LIBMPQ_EFILE_FORMAT; + } + } + mpq_b->filepos += mpq_a->mpqpos; + } + + return LIBMPQ_TOOLS_SUCCESS; } int libmpq_file_read_block(mpq_archive *mpq_a, mpq_file *mpq_f, unsigned int blockpos, char *buffer, unsigned int blockbytes) { - unsigned char *tempbuf = NULL; /* Buffer for reading compressed data from the file */ - unsigned int readpos; /* Reading position from the file */ - unsigned int toread = 0; /* Number of bytes to read */ - unsigned int blocknum; /* Block number (needed for decrypt) */ - unsigned int bytesread = 0; /* Total number of bytes read */ - unsigned int nblocks; /* Number of blocks to load */ - unsigned int i; - - /* Test parameters. Block position and block size must be block-aligned, block size nonzero */ - if ((blockpos & (mpq_a->blocksize - 1)) || blockbytes == 0) { - return 0; - } - - /* Check the end of file */ - if ((blockpos + blockbytes) > mpq_f->mpq_b->fsize) { - blockbytes = mpq_f->mpq_b->fsize - blockpos; - } - blocknum = blockpos / mpq_a->blocksize; - nblocks = blockbytes / mpq_a->blocksize; - if (blockbytes % mpq_a->blocksize) { - nblocks++; - } - - /* If file has variable block positions, we have to load them */ - if ((mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) && mpq_f->blockposloaded == FALSE) { - unsigned int nread; - - if (mpq_f->mpq_b->filepos != mpq_a->filepos) { - #ifdef WIN32 - _lseeki64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); - #else - lseek64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); - - #endif - } - - /* Read block positions from begin of file. */ - nread = (mpq_f->nblocks + 1) * sizeof(int); - nread = _read(mpq_a->fd, mpq_f->blockpos, nread); - - /* - * If the archive is protected some way, perform additional check - * Sometimes, the file appears not to be encrypted, but it is. - */ - /*if (mpq_f->blockpos[0] != nread) { - mpq_f->mpq_b->flags |= LIBMPQ_FILE_ENCRYPTED; - }*/ + unsigned char *tempbuf = NULL; /* Buffer for reading compressed data from the file */ + unsigned int readpos; /* Reading position from the file */ + unsigned int toread = 0; /* Number of bytes to read */ + unsigned int blocknum; /* Block number (needed for decrypt) */ + unsigned int bytesread = 0; /* Total number of bytes read */ + unsigned int nblocks; /* Number of blocks to load */ + unsigned int i; + + /* Test parameters. Block position and block size must be block-aligned, block size nonzero */ + if ((blockpos & (mpq_a->blocksize - 1)) || blockbytes == 0) { + return 0; + } + + /* Check the end of file */ + if ((blockpos + blockbytes) > mpq_f->mpq_b->fsize) { + blockbytes = mpq_f->mpq_b->fsize - blockpos; + } + blocknum = blockpos / mpq_a->blocksize; + nblocks = blockbytes / mpq_a->blocksize; + if (blockbytes % mpq_a->blocksize) { + nblocks++; + } + + /* If file has variable block positions, we have to load them */ + if ((mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) && mpq_f->blockposloaded == FALSE) { + unsigned int nread; + + if (mpq_f->mpq_b->filepos != mpq_a->filepos) { + #ifdef WIN32 + _lseeki64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); + #else + lseek64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); + + #endif + } + + /* Read block positions from begin of file. */ + nread = (mpq_f->nblocks + 1) * sizeof(int); + nread = _read(mpq_a->fd, mpq_f->blockpos, nread); + + /* + * If the archive is protected some way, perform additional check + * Sometimes, the file appears not to be encrypted, but it is. + */ + /*if (mpq_f->blockpos[0] != nread) { + mpq_f->mpq_b->flags |= LIBMPQ_FILE_ENCRYPTED; + }*/ if ((mpq_f->mpq_b->flags & LIBMPQ_FILE_HAS_METADATA) == 0) { if (mpq_f->blockpos[0] != nread) { - mpq_f->mpq_b->flags |= LIBMPQ_FILE_ENCRYPTED; - } + mpq_f->mpq_b->flags |= LIBMPQ_FILE_ENCRYPTED; + } } - /* Decrypt loaded block positions if necessary */ - if (mpq_f->mpq_b->flags & LIBMPQ_FILE_ENCRYPTED) { - - /* If we don't know the file seed, try to find it. */ - if (mpq_f->seed == 0) { - mpq_f->seed = libmpq_detect_fileseed(mpq_a, mpq_f->blockpos, nread); - } - - /* If we don't know the file seed, sorry but we cannot extract the file. */ - if (mpq_f->seed == 0) { - return 0; - } - - /* Decrypt block positions */ - libmpq_decrypt_block(mpq_a, mpq_f->blockpos, nread, mpq_f->seed - 1); - - /* - * Check if the block positions are correctly decrypted - * I don't know why, but sometimes it will result invalid - * block positions on some files. - */ - if (mpq_f->blockpos[0] != nread) { - - /* Try once again to detect file seed and decrypt the blocks */ - - #ifdef WIN32 - _lseeki64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); - #else - lseek64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); - #endif - - nread = _read(mpq_a->fd, mpq_f->blockpos, (mpq_f->nblocks + 1) * sizeof(int)); - mpq_f->seed = libmpq_detect_fileseed(mpq_a, mpq_f->blockpos, nread); - libmpq_decrypt_block(mpq_a, mpq_f->blockpos, nread, mpq_f->seed - 1); - - /* Check if the block positions are correctly decrypted. */ - if (mpq_f->blockpos[0] != nread) { - return 0; - } - } - } - - /* Update mpq_f's variables */ - mpq_f->blockposloaded = TRUE; - mpq_a->filepos = mpq_f->mpq_b->filepos + nread; - } - - /* Get file position and number of bytes to read */ - readpos = blockpos; - toread = blockbytes; - - if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { - readpos = mpq_f->blockpos[blocknum]; - toread = mpq_f->blockpos[blocknum + nblocks] - readpos; - } - - readpos += mpq_f->mpq_b->filepos; - - /* Get work buffer for store read data */ + /* Decrypt loaded block positions if necessary */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_ENCRYPTED) { + + /* If we don't know the file seed, try to find it. */ + if (mpq_f->seed == 0) { + mpq_f->seed = libmpq_detect_fileseed(mpq_a, mpq_f->blockpos, nread); + } + + /* If we don't know the file seed, sorry but we cannot extract the file. */ + if (mpq_f->seed == 0) { + return 0; + } + + /* Decrypt block positions */ + libmpq_decrypt_block(mpq_a, mpq_f->blockpos, nread, mpq_f->seed - 1); + + /* + * Check if the block positions are correctly decrypted + * I don't know why, but sometimes it will result invalid + * block positions on some files. + */ + if (mpq_f->blockpos[0] != nread) { + + /* Try once again to detect file seed and decrypt the blocks */ + + #ifdef WIN32 + _lseeki64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); + #else + lseek64(mpq_a->fd, mpq_f->mpq_b->filepos, SEEK_SET); + #endif + + nread = _read(mpq_a->fd, mpq_f->blockpos, (mpq_f->nblocks + 1) * sizeof(int)); + mpq_f->seed = libmpq_detect_fileseed(mpq_a, mpq_f->blockpos, nread); + libmpq_decrypt_block(mpq_a, mpq_f->blockpos, nread, mpq_f->seed - 1); + + /* Check if the block positions are correctly decrypted. */ + if (mpq_f->blockpos[0] != nread) { + return 0; + } + } + } + + /* Update mpq_f's variables */ + mpq_f->blockposloaded = TRUE; + mpq_a->filepos = mpq_f->mpq_b->filepos + nread; + } + + /* Get file position and number of bytes to read */ + readpos = blockpos; + toread = blockbytes; + + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { + readpos = mpq_f->blockpos[blocknum]; + toread = mpq_f->blockpos[blocknum + nblocks] - readpos; + } + + readpos += mpq_f->mpq_b->filepos; + + /* Get work buffer for store read data */ if ((tempbuf = (unsigned char *)malloc(toread)) == NULL) { /* Hmmm... We should add a better error handling here :) */ return 0; } - /* Set file pointer, if necessary. */ - if (mpq_a->filepos != readpos) { - - #ifdef WIN32 - mpq_a->filepos = _lseeki64(mpq_a->fd, readpos, SEEK_SET); - #else - mpq_a->filepos = lseek64(mpq_a->fd, readpos, SEEK_SET); - #endif - - } - - /* 15018F87 - Read all requested blocks. */ - bytesread = _read(mpq_a->fd, tempbuf, toread); - mpq_a->filepos = readpos + bytesread; - - /* Block processing part. */ - unsigned int blockstart = 0; /* Index of block start in work buffer. */ - unsigned int blocksize = min(blockbytes, mpq_a->blocksize); - unsigned int index = blocknum; /* Current block index. */ - bytesread = 0; /* Clear read byte counter */ - - /* Walk through all blocks. */ - for (i = 0; i < nblocks; i++, index++) { - int outlength = mpq_a->blocksize; - - /* Get current block length */ - if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { - blocksize = mpq_f->blockpos[index + 1] - mpq_f->blockpos[index]; - } - - /* If block is encrypted, we have to decrypt it. */ - if (mpq_f->mpq_b->flags & LIBMPQ_FILE_ENCRYPTED) { - if (mpq_f->seed == 0) { - return 0; - } - libmpq_decrypt_block(mpq_a, (unsigned int *)&tempbuf[blockstart], blocksize, mpq_f->seed + index); - } - - /* - * If the block is really compressed, recompress it. - * WARNING: Some block may not be compressed, it can - * only be determined by comparing uncompressed and - * compressed size! - */ - if (blocksize < blockbytes) { - - /* Is the file compressed with PKWARE Data Compression Library? */ - if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESS_PKWARE) { - libmpq_pkzip_decompress(buffer, &outlength, (char *)&tempbuf[blockstart], blocksize); - } - - /* - * Is it a file compressed by Blizzard's multiple compression ? - * Note that Storm.dll v 1.0.9 distributed with Warcraft III - * passes the full path name of the opened archive as the new - * last parameter. - */ - if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESS_MULTI) { - libmpq_multi_decompress(buffer, &outlength, (char *)&tempbuf[blockstart], blocksize); - } - bytesread += outlength; - buffer += outlength; - } else { - memcpy(buffer, tempbuf, blocksize); - bytesread += blocksize; - buffer += blocksize; - } - blockstart += blocksize; - } - - /* Delete input buffer, if necessary. */ + /* Set file pointer, if necessary. */ + if (mpq_a->filepos != readpos) { + + #ifdef WIN32 + mpq_a->filepos = _lseeki64(mpq_a->fd, readpos, SEEK_SET); + #else + mpq_a->filepos = lseek64(mpq_a->fd, readpos, SEEK_SET); + #endif + + } + + /* 15018F87 - Read all requested blocks. */ + bytesread = _read(mpq_a->fd, tempbuf, toread); + mpq_a->filepos = readpos + bytesread; + + /* Block processing part. */ + unsigned int blockstart = 0; /* Index of block start in work buffer. */ + unsigned int blocksize = min(blockbytes, mpq_a->blocksize); + unsigned int index = blocknum; /* Current block index. */ + bytesread = 0; /* Clear read byte counter */ + + /* Walk through all blocks. */ + for (i = 0; i < nblocks; i++, index++) { + int outlength = mpq_a->blocksize; + + /* Get current block length */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { + blocksize = mpq_f->blockpos[index + 1] - mpq_f->blockpos[index]; + } + + /* If block is encrypted, we have to decrypt it. */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_ENCRYPTED) { + if (mpq_f->seed == 0) { + return 0; + } + libmpq_decrypt_block(mpq_a, (unsigned int *)&tempbuf[blockstart], blocksize, mpq_f->seed + index); + } + + /* + * If the block is really compressed, recompress it. + * WARNING: Some block may not be compressed, it can + * only be determined by comparing uncompressed and + * compressed size! + */ + if (blocksize < blockbytes) { + + /* Is the file compressed with PKWARE Data Compression Library? */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESS_PKWARE) { + libmpq_pkzip_decompress(buffer, &outlength, (char *)&tempbuf[blockstart], blocksize); + } + + /* + * Is it a file compressed by Blizzard's multiple compression ? + * Note that Storm.dll v 1.0.9 distributed with Warcraft III + * passes the full path name of the opened archive as the new + * last parameter. + */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESS_MULTI) { + libmpq_multi_decompress(buffer, &outlength, (char *)&tempbuf[blockstart], blocksize); + } + bytesread += outlength; + buffer += outlength; + } else { + memcpy(buffer, tempbuf, blocksize); + bytesread += blocksize; + buffer += blocksize; + } + blockstart += blocksize; + } + + /* Delete input buffer, if necessary. */ free(tempbuf); return bytesread; } int libmpq_file_read_file(mpq_archive *mpq_a, mpq_file *mpq_f, unsigned int filepos, char *buffer, unsigned int toread) { - unsigned int bytesread = 0; /* Number of bytes read from the file */ - unsigned int blockpos; /* Position in the file aligned to the whole blocks */ - unsigned int loaded = 0; - - /* File position is greater or equal to file size? */ - if (filepos >= mpq_f->mpq_b->fsize) { - return 0; - } - - /* If to few bytes in the file remaining, cut them */ - if ((mpq_f->mpq_b->fsize - filepos) < toread) { - toread = (mpq_f->mpq_b->fsize - filepos); - } - - /* Block position in the file */ - blockpos = filepos & ~(mpq_a->blocksize - 1); - - /* - * Load the first block, if noncomplete. It may be loaded in the cache buffer. - * We have to check if this block is loaded. If not, load it. - */ - if ((filepos % mpq_a->blocksize) != 0) { - /* Number of bytes remaining in the buffer */ - unsigned int tocopy; - unsigned int loaded = mpq_a->blocksize; - - /* Check if data are loaded in the cache */ - if (mpq_f->accessed == FALSE || blockpos != mpq_a->blockpos) { - - /* Load one MPQ block into archive buffer */ - loaded = libmpq_file_read_block(mpq_a, mpq_f, blockpos, (char *)mpq_a->blockbuf, mpq_a->blocksize); - if (loaded == 0) { - return 0; - } - - /* Save lastly accessed file and block position for later use */ - mpq_f->accessed = TRUE; - mpq_a->blockpos = blockpos; - mpq_a->bufpos = filepos % mpq_a->blocksize; - } - tocopy = loaded - mpq_a->bufpos; - if (tocopy > toread) { - tocopy = toread; - } - - /* Copy data from block buffer into target buffer */ - memcpy(buffer, mpq_a->blockbuf + mpq_a->bufpos, tocopy); - - /* Update pointers */ - toread -= tocopy; - bytesread += tocopy; - buffer += tocopy; - blockpos += mpq_a->blocksize; - mpq_a->bufpos += tocopy; - - /* If all, return. */ - if (toread == 0) { - return bytesread; - } - } - - /* Load the whole ("middle") blocks only if there are more or equal one block */ - if (toread > mpq_a->blocksize) { - unsigned int blockbytes = toread & ~(mpq_a->blocksize - 1); - loaded = libmpq_file_read_block(mpq_a, mpq_f, blockpos, buffer, blockbytes); - if (loaded == 0) { - return 0; - } - - /* Update pointers */ - toread -= loaded; - bytesread += loaded; - buffer += loaded; - blockpos += loaded; - - /* If all, return. */ - if (toread == 0) { - return bytesread; - } - } - - /* Load the terminating block */ - if (toread > 0) { - unsigned int tocopy = mpq_a->blocksize; - - /* Check if data are loaded in the cache */ - if (mpq_f->accessed == FALSE || blockpos != mpq_a->blockpos) { - - /* Load one MPQ block into archive buffer */ - tocopy = libmpq_file_read_block(mpq_a, mpq_f, blockpos, (char *)mpq_a->blockbuf, mpq_a->blocksize); - if (tocopy == 0) { - return 0; - } - - /* Save lastly accessed file and block position for later use */ - mpq_f->accessed = TRUE; - mpq_a->blockpos = blockpos; - } - mpq_a->bufpos = 0; - - /* Check number of bytes read */ - if (tocopy > toread) { - tocopy = toread; - } - - memcpy(buffer, mpq_a->blockbuf, tocopy); - bytesread += tocopy; - mpq_a->bufpos = tocopy; - } - - /* Return what we've read */ - return bytesread; + unsigned int bytesread = 0; /* Number of bytes read from the file */ + unsigned int blockpos; /* Position in the file aligned to the whole blocks */ + unsigned int loaded = 0; + + /* File position is greater or equal to file size? */ + if (filepos >= mpq_f->mpq_b->fsize) { + return 0; + } + + /* If to few bytes in the file remaining, cut them */ + if ((mpq_f->mpq_b->fsize - filepos) < toread) { + toread = (mpq_f->mpq_b->fsize - filepos); + } + + /* Block position in the file */ + blockpos = filepos & ~(mpq_a->blocksize - 1); + + /* + * Load the first block, if noncomplete. It may be loaded in the cache buffer. + * We have to check if this block is loaded. If not, load it. + */ + if ((filepos % mpq_a->blocksize) != 0) { + /* Number of bytes remaining in the buffer */ + unsigned int tocopy; + unsigned int loaded = mpq_a->blocksize; + + /* Check if data are loaded in the cache */ + if (mpq_f->accessed == FALSE || blockpos != mpq_a->blockpos) { + + /* Load one MPQ block into archive buffer */ + loaded = libmpq_file_read_block(mpq_a, mpq_f, blockpos, (char *)mpq_a->blockbuf, mpq_a->blocksize); + if (loaded == 0) { + return 0; + } + + /* Save lastly accessed file and block position for later use */ + mpq_f->accessed = TRUE; + mpq_a->blockpos = blockpos; + mpq_a->bufpos = filepos % mpq_a->blocksize; + } + tocopy = loaded - mpq_a->bufpos; + if (tocopy > toread) { + tocopy = toread; + } + + /* Copy data from block buffer into target buffer */ + memcpy(buffer, mpq_a->blockbuf + mpq_a->bufpos, tocopy); + + /* Update pointers */ + toread -= tocopy; + bytesread += tocopy; + buffer += tocopy; + blockpos += mpq_a->blocksize; + mpq_a->bufpos += tocopy; + + /* If all, return. */ + if (toread == 0) { + return bytesread; + } + } + + /* Load the whole ("middle") blocks only if there are more or equal one block */ + if (toread > mpq_a->blocksize) { + unsigned int blockbytes = toread & ~(mpq_a->blocksize - 1); + loaded = libmpq_file_read_block(mpq_a, mpq_f, blockpos, buffer, blockbytes); + if (loaded == 0) { + return 0; + } + + /* Update pointers */ + toread -= loaded; + bytesread += loaded; + buffer += loaded; + blockpos += loaded; + + /* If all, return. */ + if (toread == 0) { + return bytesread; + } + } + + /* Load the terminating block */ + if (toread > 0) { + unsigned int tocopy = mpq_a->blocksize; + + /* Check if data are loaded in the cache */ + if (mpq_f->accessed == FALSE || blockpos != mpq_a->blockpos) { + + /* Load one MPQ block into archive buffer */ + tocopy = libmpq_file_read_block(mpq_a, mpq_f, blockpos, (char *)mpq_a->blockbuf, mpq_a->blocksize); + if (tocopy == 0) { + return 0; + } + + /* Save lastly accessed file and block position for later use */ + mpq_f->accessed = TRUE; + mpq_a->blockpos = blockpos; + } + mpq_a->bufpos = 0; + + /* Check number of bytes read */ + if (tocopy > toread) { + tocopy = toread; + } + + memcpy(buffer, mpq_a->blockbuf, tocopy); + bytesread += tocopy; + mpq_a->bufpos = tocopy; + } + + /* Return what we've read */ + return bytesread; } diff --git a/contrib/extractor/libmpq/common.h b/contrib/extractor/libmpq/common.h index 5794c162e10..517d959b346 100644 --- a/contrib/extractor/libmpq/common.h +++ b/contrib/extractor/libmpq/common.h @@ -20,33 +20,33 @@ * $Id: common.h,v 1.4 2004/02/12 00:41:55 mbroemme Exp $ */ -#define LIBMPQ_CONF_FL_INCREMENT 512 /* i hope we did not need more :) */ -#define LIBMPQ_CONF_EXT ".conf" /* listdb file seems to be valid with this extension */ -#define LIBMPQ_CONF_HEADER "LIBMPQ_VERSION" /* listdb file must include this entry to be valid */ -#define LIBMPQ_CONF_BUFSIZE 4096 /* maximum number of bytes a line in the file could contain */ +#define LIBMPQ_CONF_FL_INCREMENT 512 /* i hope we did not need more :) */ +#define LIBMPQ_CONF_EXT ".conf" /* listdb file seems to be valid with this extension */ +#define LIBMPQ_CONF_HEADER "LIBMPQ_VERSION" /* listdb file must include this entry to be valid */ +#define LIBMPQ_CONF_BUFSIZE 4096 /* maximum number of bytes a line in the file could contain */ -#define LIBMPQ_CONF_TYPE_CHAR 1 /* value in config file is from type char */ -#define LIBMPQ_CONF_TYPE_INT 2 /* value in config file is from type int */ +#define LIBMPQ_CONF_TYPE_CHAR 1 /* value in config file is from type char */ +#define LIBMPQ_CONF_TYPE_INT 2 /* value in config file is from type int */ -#define LIBMPQ_CONF_EOPEN_DIR -1 /* error on open directory */ -#define LIBMPQ_CONF_EVALUE_NOT_FOUND -2 /* value for the option was not found */ +#define LIBMPQ_CONF_EOPEN_DIR -1 /* error on open directory */ +#define LIBMPQ_CONF_EVALUE_NOT_FOUND -2 /* value for the option was not found */ #if defined( __GNUC__ ) - #include <sys/types.h> - #include <unistd.h> + #include <sys/types.h> + #include <unistd.h> - #define _lseek lseek - #define _read read - #define _open open - #define _write write - #define _close close - #define _strdup strdup + #define _lseek lseek + #define _read read + #define _open open + #define _write write + #define _close close + #define _strdup strdup - #ifndef O_BINARY - #define O_BINARY 0 - #endif + #ifndef O_BINARY + #define O_BINARY 0 + #endif #else - #include <io.h> + #include <io.h> #endif #ifdef O_LARGEFILE @@ -56,7 +56,7 @@ #endif #ifndef min - #define min(a, b) ((a < b) ? a : b) + #define min(a, b) ((a < b) ? a : b) #endif int libmpq_init_buffer(mpq_archive *mpq_a); diff --git a/contrib/extractor/libmpq/explode.cpp b/contrib/extractor/libmpq/explode.cpp index bcf9e7857a2..1401dd4ad5f 100644 --- a/contrib/extractor/libmpq/explode.cpp +++ b/contrib/extractor/libmpq/explode.cpp @@ -31,88 +31,88 @@ /* Tables */ static unsigned char pkzip_dist_bits[] = { - 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 + 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }; static unsigned char pkzip_dist_code[] = { - 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, - 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, - 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, - 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 + 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, + 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, + 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, + 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 }; static unsigned char pkzip_clen_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; static unsigned short pkzip_len_base[] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106 + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106 }; static unsigned char pkzip_slen_bits[] = { - 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 + 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 }; static unsigned char pkzip_len_code[] = { - 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 + 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 }; static unsigned char pkzip_bits_asc[] = { - 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, - 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, - 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, - 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, - 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, - 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, - 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, - 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D + 0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, + 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, + 0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, + 0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, + 0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, + 0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, + 0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D }; static unsigned short pkzip_code_asc[] = { - 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, - 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, - 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, - 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, - 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, - 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, - 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, - 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, - 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, - 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, - 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, - 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, - 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, - 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, - 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, - 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, - 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, - 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, - 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, - 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, - 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, - 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, - 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, - 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, - 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, - 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, - 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, - 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, - 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, - 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, - 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, - 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 + 0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, + 0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, + 0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, + 0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, + 0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, + 0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, + 0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, + 0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, + 0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, + 0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, + 0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, + 0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, + 0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, + 0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, + 0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, + 0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, + 0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, + 0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, + 0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, + 0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, + 0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, + 0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, + 0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, + 0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, + 0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, + 0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, + 0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, + 0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, + 0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, + 0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, + 0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, + 0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000 }; /* Local variables */ @@ -124,68 +124,68 @@ static char copyright[] = "PKWARE Data Compression Library for Win32\r\n" /* Local functions */ static void libmpq_pkzip_gen_decode_tabs(long count, unsigned char *bits, unsigned char *code, unsigned char *buf2) { - long i; - - for (i = count-1; i >= 0; i--) { /* EBX - count */ - unsigned long idx1 = code[i]; - unsigned long idx2 = 1 << bits[i]; - do { - buf2[idx1] = (unsigned char)i; - idx1 += idx2; - } while (idx1 < 0x100); - } + long i; + + for (i = count-1; i >= 0; i--) { /* EBX - count */ + unsigned long idx1 = code[i]; + unsigned long idx2 = 1 << bits[i]; + do { + buf2[idx1] = (unsigned char)i; + idx1 += idx2; + } while (idx1 < 0x100); + } } static void libmpq_pkzip_gen_asc_tabs(pkzip_data_cmp *mpq_pkzip) { - unsigned short *code_asc = &pkzip_code_asc[0xFF]; - unsigned long acc, add; - unsigned short count; - - for (count = 0x00FF; code_asc >= pkzip_code_asc; code_asc--, count--) { - unsigned char *bits_asc = mpq_pkzip->bits_asc + count; - unsigned char bits_tmp = *bits_asc; - - if (bits_tmp <= 8) { - add = (1 << bits_tmp); - acc = *code_asc; - do { - mpq_pkzip->offs_2c34[acc] = (unsigned char)count; - acc += add; - } while (acc < 0x100); - } else { - if ((acc = (*code_asc & 0xFF)) != 0) { - mpq_pkzip->offs_2c34[acc] = 0xFF; - if (*code_asc & 0x3F) { - bits_tmp -= 4; - *bits_asc = bits_tmp; - add = (1 << bits_tmp); - acc = *code_asc >> 4; - do { - mpq_pkzip->offs_2d34[acc] = (unsigned char)count; - acc += add; - } while (acc < 0x100); - } else { - bits_tmp -= 6; - *bits_asc = bits_tmp; - add = (1 << bits_tmp); - acc = *code_asc >> 6; - do { - mpq_pkzip->offs_2e34[acc] = (unsigned char)count; - acc += add; - } while (acc < 0x80); - } - } else { - bits_tmp -= 8; - *bits_asc = bits_tmp; - add = (1 << bits_tmp); - acc = *code_asc >> 8; - do { - mpq_pkzip->offs_2eb4[acc] = (unsigned char)count; - acc += add; - } while (acc < 0x100); - } - } - } + unsigned short *code_asc = &pkzip_code_asc[0xFF]; + unsigned long acc, add; + unsigned short count; + + for (count = 0x00FF; code_asc >= pkzip_code_asc; code_asc--, count--) { + unsigned char *bits_asc = mpq_pkzip->bits_asc + count; + unsigned char bits_tmp = *bits_asc; + + if (bits_tmp <= 8) { + add = (1 << bits_tmp); + acc = *code_asc; + do { + mpq_pkzip->offs_2c34[acc] = (unsigned char)count; + acc += add; + } while (acc < 0x100); + } else { + if ((acc = (*code_asc & 0xFF)) != 0) { + mpq_pkzip->offs_2c34[acc] = 0xFF; + if (*code_asc & 0x3F) { + bits_tmp -= 4; + *bits_asc = bits_tmp; + add = (1 << bits_tmp); + acc = *code_asc >> 4; + do { + mpq_pkzip->offs_2d34[acc] = (unsigned char)count; + acc += add; + } while (acc < 0x100); + } else { + bits_tmp -= 6; + *bits_asc = bits_tmp; + add = (1 << bits_tmp); + acc = *code_asc >> 6; + do { + mpq_pkzip->offs_2e34[acc] = (unsigned char)count; + acc += add; + } while (acc < 0x80); + } + } else { + bits_tmp -= 8; + *bits_asc = bits_tmp; + add = (1 << bits_tmp); + acc = *code_asc >> 8; + do { + mpq_pkzip->offs_2eb4[acc] = (unsigned char)count; + acc += add; + } while (acc < 0x100); + } + } + } } /* @@ -193,28 +193,28 @@ static void libmpq_pkzip_gen_asc_tabs(pkzip_data_cmp *mpq_pkzip) { * If no data in input buffer, returns true */ static int libmpq_pkzip_skip_bits(pkzip_data_cmp *mpq_pkzip, unsigned long bits) { - /* If number of bits required is less than number of (bits in the buffer) ? */ - if (bits <= mpq_pkzip->extra_bits) { - mpq_pkzip->extra_bits -= bits; - mpq_pkzip->bit_buf >>= bits; - return 0; - } - - /* Load input buffer if necessary */ - mpq_pkzip->bit_buf >>= mpq_pkzip->extra_bits; - if (mpq_pkzip->in_pos == mpq_pkzip->in_bytes) { - mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf); - if ((mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param)) == 0) { - return 1; - } - mpq_pkzip->in_pos = 0; - } - - /* Update bit buffer */ - mpq_pkzip->bit_buf |= (mpq_pkzip->in_buf[mpq_pkzip->in_pos++] << 8); - mpq_pkzip->bit_buf >>= (bits - mpq_pkzip->extra_bits); - mpq_pkzip->extra_bits = (mpq_pkzip->extra_bits - bits) + 8; - return 0; + /* If number of bits required is less than number of (bits in the buffer) ? */ + if (bits <= mpq_pkzip->extra_bits) { + mpq_pkzip->extra_bits -= bits; + mpq_pkzip->bit_buf >>= bits; + return 0; + } + + /* Load input buffer if necessary */ + mpq_pkzip->bit_buf >>= mpq_pkzip->extra_bits; + if (mpq_pkzip->in_pos == mpq_pkzip->in_bytes) { + mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf); + if ((mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param)) == 0) { + return 1; + } + mpq_pkzip->in_pos = 0; + } + + /* Update bit buffer */ + mpq_pkzip->bit_buf |= (mpq_pkzip->in_buf[mpq_pkzip->in_pos++] << 8); + mpq_pkzip->bit_buf >>= (bits - mpq_pkzip->extra_bits); + mpq_pkzip->extra_bits = (mpq_pkzip->extra_bits - bits) + 8; + return 0; } /* @@ -224,205 +224,205 @@ static int libmpq_pkzip_skip_bits(pkzip_data_cmp *mpq_pkzip, unsigned long bits) * 0x306 : Out of buffer (?) */ static unsigned long libmpq_pkzip_explode_lit(pkzip_data_cmp *mpq_pkzip) { - unsigned long bits; /* Number of bits to skip */ - unsigned long value; /* Position in buffers */ - - /* Test the current bit in byte buffer. If is not set, simply return the next byte. */ - if (mpq_pkzip->bit_buf & 1) { - - /* Skip current bit in the buffer. */ - if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) { - return 0x306; - } - - /* The next bits are position in buffers. */ - value = mpq_pkzip->pos2[(mpq_pkzip->bit_buf & 0xFF)]; - - /* Get number of bits to skip */ - if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->slen_bits[value])) { - return 0x306; - } - if ((bits = mpq_pkzip->clen_bits[value]) != 0) { - unsigned long val2 = mpq_pkzip->bit_buf & ((1 << bits) - 1); - if (libmpq_pkzip_skip_bits(mpq_pkzip, bits)) { - if ((value + val2) != 0x10E) { - return 0x306; - } - } - value = mpq_pkzip->len_base[value] + val2; - } - return value + 0x100; /* Return number of bytes to repeat */ - } - - /* Skip one bit */ - if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) { - return 0x306; - } - - /* If the binary compression type, read 8 bits and return them as one byte. */ - if (mpq_pkzip->cmp_type == LIBMPQ_PKZIP_CMP_BINARY) { - value = mpq_pkzip->bit_buf & 0xFF; - if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) { - return 0x306; - } - return value; - } - - /* When ASCII compression ... */ - if (mpq_pkzip->bit_buf & 0xFF) { - value = mpq_pkzip->offs_2c34[mpq_pkzip->bit_buf & 0xFF]; - if (value == 0xFF) { - if (mpq_pkzip->bit_buf & 0x3F) { - if (libmpq_pkzip_skip_bits(mpq_pkzip, 4)) { - return 0x306; - } - value = mpq_pkzip->offs_2d34[mpq_pkzip->bit_buf & 0xFF]; - } else { - if (libmpq_pkzip_skip_bits(mpq_pkzip, 6)) { - return 0x306; - } - value = mpq_pkzip->offs_2e34[mpq_pkzip->bit_buf & 0x7F]; - } - } - } else { - if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) { - return 0x306; - } - value = mpq_pkzip->offs_2eb4[mpq_pkzip->bit_buf & 0xFF]; - } - return libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->bits_asc[value]) ? 0x306 : value; + unsigned long bits; /* Number of bits to skip */ + unsigned long value; /* Position in buffers */ + + /* Test the current bit in byte buffer. If is not set, simply return the next byte. */ + if (mpq_pkzip->bit_buf & 1) { + + /* Skip current bit in the buffer. */ + if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) { + return 0x306; + } + + /* The next bits are position in buffers. */ + value = mpq_pkzip->pos2[(mpq_pkzip->bit_buf & 0xFF)]; + + /* Get number of bits to skip */ + if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->slen_bits[value])) { + return 0x306; + } + if ((bits = mpq_pkzip->clen_bits[value]) != 0) { + unsigned long val2 = mpq_pkzip->bit_buf & ((1 << bits) - 1); + if (libmpq_pkzip_skip_bits(mpq_pkzip, bits)) { + if ((value + val2) != 0x10E) { + return 0x306; + } + } + value = mpq_pkzip->len_base[value] + val2; + } + return value + 0x100; /* Return number of bytes to repeat */ + } + + /* Skip one bit */ + if (libmpq_pkzip_skip_bits(mpq_pkzip, 1)) { + return 0x306; + } + + /* If the binary compression type, read 8 bits and return them as one byte. */ + if (mpq_pkzip->cmp_type == LIBMPQ_PKZIP_CMP_BINARY) { + value = mpq_pkzip->bit_buf & 0xFF; + if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) { + return 0x306; + } + return value; + } + + /* When ASCII compression ... */ + if (mpq_pkzip->bit_buf & 0xFF) { + value = mpq_pkzip->offs_2c34[mpq_pkzip->bit_buf & 0xFF]; + if (value == 0xFF) { + if (mpq_pkzip->bit_buf & 0x3F) { + if (libmpq_pkzip_skip_bits(mpq_pkzip, 4)) { + return 0x306; + } + value = mpq_pkzip->offs_2d34[mpq_pkzip->bit_buf & 0xFF]; + } else { + if (libmpq_pkzip_skip_bits(mpq_pkzip, 6)) { + return 0x306; + } + value = mpq_pkzip->offs_2e34[mpq_pkzip->bit_buf & 0x7F]; + } + } + } else { + if (libmpq_pkzip_skip_bits(mpq_pkzip, 8)) { + return 0x306; + } + value = mpq_pkzip->offs_2eb4[mpq_pkzip->bit_buf & 0xFF]; + } + return libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->bits_asc[value]) ? 0x306 : value; } /* * Retrieves the number of bytes to move back. */ static unsigned long libmpq_pkzip_explode_dist(pkzip_data_cmp *mpq_pkzip, unsigned long length) { - unsigned long pos = mpq_pkzip->pos1[(mpq_pkzip->bit_buf & 0xFF)]; - unsigned long skip = mpq_pkzip->dist_bits[pos]; /* Number of bits to skip */ - - /* Skip the appropriate number of bits */ - if (libmpq_pkzip_skip_bits(mpq_pkzip, skip) == 1) { - return 0; - } - if (length == 2) { - pos = (pos << 2) | (mpq_pkzip->bit_buf & 0x03); - if (libmpq_pkzip_skip_bits(mpq_pkzip, 2) == 1) { - return 0; - } - } else { - pos = (pos << mpq_pkzip->dsize_bits) | (mpq_pkzip->bit_buf & mpq_pkzip->dsize_mask); - - /* Skip the bits */ - if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->dsize_bits) == 1) { - return 0; - } - } - return pos + 1; + unsigned long pos = mpq_pkzip->pos1[(mpq_pkzip->bit_buf & 0xFF)]; + unsigned long skip = mpq_pkzip->dist_bits[pos]; /* Number of bits to skip */ + + /* Skip the appropriate number of bits */ + if (libmpq_pkzip_skip_bits(mpq_pkzip, skip) == 1) { + return 0; + } + if (length == 2) { + pos = (pos << 2) | (mpq_pkzip->bit_buf & 0x03); + if (libmpq_pkzip_skip_bits(mpq_pkzip, 2) == 1) { + return 0; + } + } else { + pos = (pos << mpq_pkzip->dsize_bits) | (mpq_pkzip->bit_buf & mpq_pkzip->dsize_mask); + + /* Skip the bits */ + if (libmpq_pkzip_skip_bits(mpq_pkzip, mpq_pkzip->dsize_bits) == 1) { + return 0; + } + } + return pos + 1; } static unsigned long libmpq_pkzip_expand(pkzip_data_cmp *mpq_pkzip) { - unsigned int copy_bytes; /* Number of bytes to copy */ - unsigned long one_byte; /* One byte from compressed file */ - unsigned long result; - - mpq_pkzip->out_pos = 0x1000; /* Initialize output buffer position */ - - /* If end of data or error, terminate decompress */ - while ((result = one_byte = libmpq_pkzip_explode_lit(mpq_pkzip)) < 0x305) { - - /* If one byte is greater than 0x100, means "Repeat n - 0xFE bytes" */ - if (one_byte >= 0x100) { - unsigned char *source; /* ECX */ - unsigned char *target; /* EDX */ - unsigned long copy_length = one_byte - 0xFE; - unsigned long move_back; - - /* Get length of data to copy */ - if ((move_back = libmpq_pkzip_explode_dist(mpq_pkzip, copy_length)) == 0) { - result = 0x306; - break; - } - - /* Target and source pointer */ - target = &mpq_pkzip->out_buf[mpq_pkzip->out_pos]; - source = target - move_back; - mpq_pkzip->out_pos += copy_length; - while (copy_length-- > 0) { - *target++ = *source++; - } - } else { - mpq_pkzip->out_buf[mpq_pkzip->out_pos++] = (unsigned char)one_byte; - } - - /* - * If number of extracted bytes has reached 1/2 of output buffer, - * flush output buffer. - */ - if (mpq_pkzip->out_pos >= 0x2000) { - - /* Copy decompressed data into user buffer. */ - copy_bytes = 0x1000; - mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], ©_bytes, mpq_pkzip->param); - - /* If there are some data left, keep them alive */ - memcpy(mpq_pkzip->out_buf, &mpq_pkzip->out_buf[0x1000], mpq_pkzip->out_pos - 0x1000); - mpq_pkzip->out_pos -= 0x1000; - } - } - copy_bytes = mpq_pkzip->out_pos - 0x1000; - mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], ©_bytes, mpq_pkzip->param); - return result; + unsigned int copy_bytes; /* Number of bytes to copy */ + unsigned long one_byte; /* One byte from compressed file */ + unsigned long result; + + mpq_pkzip->out_pos = 0x1000; /* Initialize output buffer position */ + + /* If end of data or error, terminate decompress */ + while ((result = one_byte = libmpq_pkzip_explode_lit(mpq_pkzip)) < 0x305) { + + /* If one byte is greater than 0x100, means "Repeat n - 0xFE bytes" */ + if (one_byte >= 0x100) { + unsigned char *source; /* ECX */ + unsigned char *target; /* EDX */ + unsigned long copy_length = one_byte - 0xFE; + unsigned long move_back; + + /* Get length of data to copy */ + if ((move_back = libmpq_pkzip_explode_dist(mpq_pkzip, copy_length)) == 0) { + result = 0x306; + break; + } + + /* Target and source pointer */ + target = &mpq_pkzip->out_buf[mpq_pkzip->out_pos]; + source = target - move_back; + mpq_pkzip->out_pos += copy_length; + while (copy_length-- > 0) { + *target++ = *source++; + } + } else { + mpq_pkzip->out_buf[mpq_pkzip->out_pos++] = (unsigned char)one_byte; + } + + /* + * If number of extracted bytes has reached 1/2 of output buffer, + * flush output buffer. + */ + if (mpq_pkzip->out_pos >= 0x2000) { + + /* Copy decompressed data into user buffer. */ + copy_bytes = 0x1000; + mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], ©_bytes, mpq_pkzip->param); + + /* If there are some data left, keep them alive */ + memcpy(mpq_pkzip->out_buf, &mpq_pkzip->out_buf[0x1000], mpq_pkzip->out_pos - 0x1000); + mpq_pkzip->out_pos -= 0x1000; + } + } + copy_bytes = mpq_pkzip->out_pos - 0x1000; + mpq_pkzip->write_buf((char *)&mpq_pkzip->out_buf[0x1000], ©_bytes, mpq_pkzip->param); + return result; } /* * Main exploding function. */ unsigned int libmpq_pkzip_explode( - unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), - void (*write_buf)(char *buf, unsigned int *size, void *param), - char *work_buf, - void *param) { - - pkzip_data_cmp *mpq_pkzip = (pkzip_data_cmp *)work_buf; - - /* Set the whole work buffer to zeros */ - memset(mpq_pkzip, 0, sizeof(pkzip_data_cmp)); - - /* Initialize work struct and load compressed data */ - mpq_pkzip->read_buf = read_buf; - mpq_pkzip->write_buf = write_buf; - mpq_pkzip->param = param; - mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf); - mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param); - if (mpq_pkzip->in_bytes <= 4) { - return LIBMPQ_PKZIP_CMP_BAD_DATA; - } - mpq_pkzip->cmp_type = mpq_pkzip->in_buf[0]; /* Get the compression type */ - mpq_pkzip->dsize_bits = mpq_pkzip->in_buf[1]; /* Get the dictionary size */ - mpq_pkzip->bit_buf = mpq_pkzip->in_buf[2]; /* Initialize 16-bit bit buffer */ - mpq_pkzip->extra_bits = 0; /* Extra (over 8) bits */ - mpq_pkzip->in_pos = 3; /* Position in input buffer */ - - /* Test for the valid dictionary size */ - if (4 > mpq_pkzip->dsize_bits || mpq_pkzip->dsize_bits > 6) { - return LIBMPQ_PKZIP_CMP_INV_DICTSIZE; - } - mpq_pkzip->dsize_mask = 0xFFFF >> (0x10 - mpq_pkzip->dsize_bits); /* Shifted by 'sar' instruction */ - if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_BINARY) { - if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_ASCII) { - return LIBMPQ_PKZIP_CMP_INV_MODE; - } - memcpy(mpq_pkzip->bits_asc, pkzip_bits_asc, sizeof(mpq_pkzip->bits_asc)); - libmpq_pkzip_gen_asc_tabs(mpq_pkzip); - } - memcpy(mpq_pkzip->slen_bits, pkzip_slen_bits, sizeof(mpq_pkzip->slen_bits)); - libmpq_pkzip_gen_decode_tabs(0x10, mpq_pkzip->slen_bits, pkzip_len_code, mpq_pkzip->pos2); - memcpy(mpq_pkzip->clen_bits, pkzip_clen_bits, sizeof(mpq_pkzip->clen_bits)); - memcpy(mpq_pkzip->len_base, pkzip_len_base, sizeof(mpq_pkzip->len_base)); - memcpy(mpq_pkzip->dist_bits, pkzip_dist_bits, sizeof(mpq_pkzip->dist_bits)); - libmpq_pkzip_gen_decode_tabs(0x40, mpq_pkzip->dist_bits, pkzip_dist_code, mpq_pkzip->pos1); - if (libmpq_pkzip_expand(mpq_pkzip) != 0x306) { - return LIBMPQ_PKZIP_CMP_NO_ERROR; - } - return LIBMPQ_PKZIP_CMP_ABORT; + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param) { + + pkzip_data_cmp *mpq_pkzip = (pkzip_data_cmp *)work_buf; + + /* Set the whole work buffer to zeros */ + memset(mpq_pkzip, 0, sizeof(pkzip_data_cmp)); + + /* Initialize work struct and load compressed data */ + mpq_pkzip->read_buf = read_buf; + mpq_pkzip->write_buf = write_buf; + mpq_pkzip->param = param; + mpq_pkzip->in_pos = sizeof(mpq_pkzip->in_buf); + mpq_pkzip->in_bytes = mpq_pkzip->read_buf((char *)mpq_pkzip->in_buf, &mpq_pkzip->in_pos, mpq_pkzip->param); + if (mpq_pkzip->in_bytes <= 4) { + return LIBMPQ_PKZIP_CMP_BAD_DATA; + } + mpq_pkzip->cmp_type = mpq_pkzip->in_buf[0]; /* Get the compression type */ + mpq_pkzip->dsize_bits = mpq_pkzip->in_buf[1]; /* Get the dictionary size */ + mpq_pkzip->bit_buf = mpq_pkzip->in_buf[2]; /* Initialize 16-bit bit buffer */ + mpq_pkzip->extra_bits = 0; /* Extra (over 8) bits */ + mpq_pkzip->in_pos = 3; /* Position in input buffer */ + + /* Test for the valid dictionary size */ + if (4 > mpq_pkzip->dsize_bits || mpq_pkzip->dsize_bits > 6) { + return LIBMPQ_PKZIP_CMP_INV_DICTSIZE; + } + mpq_pkzip->dsize_mask = 0xFFFF >> (0x10 - mpq_pkzip->dsize_bits); /* Shifted by 'sar' instruction */ + if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_BINARY) { + if (mpq_pkzip->cmp_type != LIBMPQ_PKZIP_CMP_ASCII) { + return LIBMPQ_PKZIP_CMP_INV_MODE; + } + memcpy(mpq_pkzip->bits_asc, pkzip_bits_asc, sizeof(mpq_pkzip->bits_asc)); + libmpq_pkzip_gen_asc_tabs(mpq_pkzip); + } + memcpy(mpq_pkzip->slen_bits, pkzip_slen_bits, sizeof(mpq_pkzip->slen_bits)); + libmpq_pkzip_gen_decode_tabs(0x10, mpq_pkzip->slen_bits, pkzip_len_code, mpq_pkzip->pos2); + memcpy(mpq_pkzip->clen_bits, pkzip_clen_bits, sizeof(mpq_pkzip->clen_bits)); + memcpy(mpq_pkzip->len_base, pkzip_len_base, sizeof(mpq_pkzip->len_base)); + memcpy(mpq_pkzip->dist_bits, pkzip_dist_bits, sizeof(mpq_pkzip->dist_bits)); + libmpq_pkzip_gen_decode_tabs(0x40, mpq_pkzip->dist_bits, pkzip_dist_code, mpq_pkzip->pos1); + if (libmpq_pkzip_expand(mpq_pkzip) != 0x306) { + return LIBMPQ_PKZIP_CMP_NO_ERROR; + } + return LIBMPQ_PKZIP_CMP_ABORT; } diff --git a/contrib/extractor/libmpq/explode.h b/contrib/extractor/libmpq/explode.h index 1f916f778ae..d8b15868a39 100644 --- a/contrib/extractor/libmpq/explode.h +++ b/contrib/extractor/libmpq/explode.h @@ -27,60 +27,60 @@ #ifndef _EXPLODE_H #define _EXPLODE_H -#define LIBMPQ_PKZIP_EXP_BUFFER_SIZE 12596 /* Size of decompress buffer */ -#define LIBMPQ_PKZIP_CMP_BINARY 0 /* Binary compression */ -#define LIBMPQ_PKZIP_CMP_ASCII 1 /* Ascii compression */ -#define LIBMPQ_PKZIP_CMP_NO_ERROR 0 -#define LIBMPQ_PKZIP_CMP_INV_DICTSIZE 1 -#define LIBMPQ_PKZIP_CMP_INV_MODE 2 -#define LIBMPQ_PKZIP_CMP_BAD_DATA 3 -#define LIBMPQ_PKZIP_CMP_ABORT 4 +#define LIBMPQ_PKZIP_EXP_BUFFER_SIZE 12596 /* Size of decompress buffer */ +#define LIBMPQ_PKZIP_CMP_BINARY 0 /* Binary compression */ +#define LIBMPQ_PKZIP_CMP_ASCII 1 /* Ascii compression */ +#define LIBMPQ_PKZIP_CMP_NO_ERROR 0 +#define LIBMPQ_PKZIP_CMP_INV_DICTSIZE 1 +#define LIBMPQ_PKZIP_CMP_INV_MODE 2 +#define LIBMPQ_PKZIP_CMP_BAD_DATA 3 +#define LIBMPQ_PKZIP_CMP_ABORT 4 /* Compression structure (size: 12596 bytes on x86-32) */ typedef struct { - unsigned long offs0000; /* 0000 */ - unsigned long cmp_type; /* 0004 - Compression type (LIBMPQ_PZIP_CMP_BINARY or LIBMPQ_PKZIP_CMP_ASCII) */ - unsigned long out_pos; /* 0008 - Position in output buffer */ - unsigned long dsize_bits; /* 000C - Dict size (4, 5, 6 for 0x400, 0x800, 0x1000) */ - unsigned long dsize_mask; /* 0010 - Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000) */ - unsigned long bit_buf; /* 0014 - 16-bit buffer for processing input data */ - unsigned long extra_bits; /* 0018 - Number of extra (above 8) bits in bit buffer */ - unsigned int in_pos; /* 001C - Position in in_buf */ - unsigned long in_bytes; /* 0020 - Number of bytes in input buffer */ - void *param; /* 0024 - Custom parameter */ - unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); /* 0028 */ - void (*write_buf)(char *buf, unsigned int *size, void *param); /* 002C */ - unsigned char out_buf[0x2000]; /* 0030 - Output circle buffer. Starting position is 0x1000 */ - unsigned char offs_2030[0x204]; /* 2030 - ??? */ - unsigned char in_buf[0x800]; /* 2234 - Buffer for data to be decompressed */ - unsigned char pos1[0x100]; /* 2A34 - Positions in buffers */ - unsigned char pos2[0x100]; /* 2B34 - Positions in buffers */ - unsigned char offs_2c34[0x100]; /* 2C34 - Buffer for */ - unsigned char offs_2d34[0x100]; /* 2D34 - Buffer for */ - unsigned char offs_2e34[0x80]; /* 2EB4 - Buffer for */ - unsigned char offs_2eb4[0x100]; /* 2EB4 - Buffer for */ - unsigned char bits_asc[0x100]; /* 2FB4 - Buffer for */ - unsigned char dist_bits[0x40]; /* 30B4 - Numbers of bytes to skip copied block length */ - unsigned char slen_bits[0x10]; /* 30F4 - Numbers of bits for skip copied block length */ - unsigned char clen_bits[0x10]; /* 3104 - Number of valid bits for copied block */ - unsigned short len_base[0x10]; /* 3114 - Buffer for */ + unsigned long offs0000; /* 0000 */ + unsigned long cmp_type; /* 0004 - Compression type (LIBMPQ_PZIP_CMP_BINARY or LIBMPQ_PKZIP_CMP_ASCII) */ + unsigned long out_pos; /* 0008 - Position in output buffer */ + unsigned long dsize_bits; /* 000C - Dict size (4, 5, 6 for 0x400, 0x800, 0x1000) */ + unsigned long dsize_mask; /* 0010 - Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000) */ + unsigned long bit_buf; /* 0014 - 16-bit buffer for processing input data */ + unsigned long extra_bits; /* 0018 - Number of extra (above 8) bits in bit buffer */ + unsigned int in_pos; /* 001C - Position in in_buf */ + unsigned long in_bytes; /* 0020 - Number of bytes in input buffer */ + void *param; /* 0024 - Custom parameter */ + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); /* 0028 */ + void (*write_buf)(char *buf, unsigned int *size, void *param); /* 002C */ + unsigned char out_buf[0x2000]; /* 0030 - Output circle buffer. Starting position is 0x1000 */ + unsigned char offs_2030[0x204]; /* 2030 - ??? */ + unsigned char in_buf[0x800]; /* 2234 - Buffer for data to be decompressed */ + unsigned char pos1[0x100]; /* 2A34 - Positions in buffers */ + unsigned char pos2[0x100]; /* 2B34 - Positions in buffers */ + unsigned char offs_2c34[0x100]; /* 2C34 - Buffer for */ + unsigned char offs_2d34[0x100]; /* 2D34 - Buffer for */ + unsigned char offs_2e34[0x80]; /* 2EB4 - Buffer for */ + unsigned char offs_2eb4[0x100]; /* 2EB4 - Buffer for */ + unsigned char bits_asc[0x100]; /* 2FB4 - Buffer for */ + unsigned char dist_bits[0x40]; /* 30B4 - Numbers of bytes to skip copied block length */ + unsigned char slen_bits[0x10]; /* 30F4 - Numbers of bits for skip copied block length */ + unsigned char clen_bits[0x10]; /* 3104 - Number of valid bits for copied block */ + unsigned short len_base[0x10]; /* 3114 - Buffer for */ } pkzip_data_cmp; // __attribute__ ((packed)) pkzip_data_cmp; typedef struct { - char *in_buf; /* Pointer to input data buffer */ - unsigned int in_pos; /* Current offset in input data buffer */ - int in_bytes; /* Number of bytes in the input buffer */ - char *out_buf; /* Pointer to output data buffer */ - unsigned int out_pos; /* Position in the output buffer */ - int max_out; /* Maximum number of bytes in the output buffer */ + char *in_buf; /* Pointer to input data buffer */ + unsigned int in_pos; /* Current offset in input data buffer */ + int in_bytes; /* Number of bytes in the input buffer */ + char *out_buf; /* Pointer to output data buffer */ + unsigned int out_pos; /* Position in the output buffer */ + int max_out; /* Maximum number of bytes in the output buffer */ } pkzip_data; extern unsigned int libmpq_pkzip_explode( - unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), - void (*write_buf)(char *buf, unsigned int *size, void *param), - char *work_buf, - void *param + unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), + void (*write_buf)(char *buf, unsigned int *size, void *param), + char *work_buf, + void *param ); -#endif /* _EXPLODE_H */ +#endif /* _EXPLODE_H */ diff --git a/contrib/extractor/libmpq/extract.cpp b/contrib/extractor/libmpq/extract.cpp index 41472b3c426..21043b75ae8 100644 --- a/contrib/extractor/libmpq/extract.cpp +++ b/contrib/extractor/libmpq/extract.cpp @@ -50,20 +50,20 @@ * void * param - Custom pointer, parameter of implode/explode */ static unsigned int libmpq_pkzip_read_input_data(char *buf, unsigned int *size, void *param) { - pkzip_data *info = (pkzip_data *)param; - unsigned int max_avail = (info->in_bytes - info->in_pos); - unsigned int to_read = *size; + pkzip_data *info = (pkzip_data *)param; + unsigned int max_avail = (info->in_bytes - info->in_pos); + unsigned int to_read = *size; - /* Check the case when not enough data available */ - if (to_read > max_avail) { - to_read = max_avail; - } + /* Check the case when not enough data available */ + if (to_read > max_avail) { + to_read = max_avail; + } - /* Load data and increment offsets */ - memcpy(buf, info->in_buf + info->in_pos, to_read); - info->in_pos += to_read; + /* Load data and increment offsets */ + memcpy(buf, info->in_buf + info->in_pos, to_read); + info->in_pos += to_read; - return to_read; + return to_read; } /* @@ -77,76 +77,76 @@ static unsigned int libmpq_pkzip_read_input_data(char *buf, unsigned int *size, * void * param - Custom pointer, parameter of implode/explode */ static void libmpq_pkzip_write_output_data(char *buf, unsigned int *size, void *param) { - pkzip_data *info = (pkzip_data *)param; - unsigned int max_write = (info->max_out - info->out_pos); - unsigned int to_write = *size; - - /* Check the case when not enough space in the output buffer */ - if (to_write > max_write) { - to_write = max_write; - } - - /* Write output data and increments offsets */ - memcpy(info->out_buf + info->out_pos, buf, to_write); - info->out_pos += to_write; + pkzip_data *info = (pkzip_data *)param; + unsigned int max_write = (info->max_out - info->out_pos); + unsigned int to_write = *size; + + /* Check the case when not enough space in the output buffer */ + if (to_write > max_write) { + to_write = max_write; + } + + /* Write output data and increments offsets */ + memcpy(info->out_buf + info->out_pos, buf, to_write); + info->out_pos += to_write; } int libmpq_pkzip_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) { - pkzip_data info; /* Data information */ - char *work_buf = (char *)malloc(LIBMPQ_PKZIP_EXP_BUFFER_SIZE); /* mpq_pkzip work buffer */ - - /* Fill data information structure */ - info.in_buf = in_buf; - info.in_pos = 0; - info.in_bytes = in_length; - info.out_buf = out_buf; - info.out_pos = 0; - info.max_out = *out_length; - - /* Do the decompression */ - libmpq_pkzip_explode(libmpq_pkzip_read_input_data, libmpq_pkzip_write_output_data, work_buf, &info); - *out_length = info.out_pos; - free(work_buf); - return 0; + pkzip_data info; /* Data information */ + char *work_buf = (char *)malloc(LIBMPQ_PKZIP_EXP_BUFFER_SIZE); /* mpq_pkzip work buffer */ + + /* Fill data information structure */ + info.in_buf = in_buf; + info.in_pos = 0; + info.in_bytes = in_length; + info.out_buf = out_buf; + info.out_pos = 0; + info.max_out = *out_length; + + /* Do the decompression */ + libmpq_pkzip_explode(libmpq_pkzip_read_input_data, libmpq_pkzip_write_output_data, work_buf, &info); + *out_length = info.out_pos; + free(work_buf); + return 0; } int libmpq_wave_decompress_mono(char *out_buf, int *out_length, char *in_buf, int in_length) { - *out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 1); - return 1; + *out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 1); + return 1; } int libmpq_wave_decompress_stereo(char *out_buf, int *out_length, char *in_buf, int in_length) { - *out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 2); - return 1; + *out_length = libmpq_wave_decompress((unsigned char *)out_buf, *out_length, (unsigned char *)in_buf, in_length, 2); + return 1; } int libmpq_zlib_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) { #ifdef HAVE_LIBZ - z_stream z; /* Stream information for zlib */ - int result; - - /* Fill the stream structure for zlib */ - z.next_in = (Bytef *)in_buf; - z.avail_in = (uInt)in_length; - z.total_in = in_length; - z.next_out = (Bytef *)out_buf; - z.avail_out = *out_length; - z.total_out = 0; - z.zalloc = NULL; - z.zfree = NULL; - - /* Initialize the decompression structure. Storm.dll uses zlib version 1.1.3 */ - if ((result = inflateInit(&z)) == 0) { - - /* Call zlib to decompress the data */ - result = inflate(&z, Z_FINISH); - *out_length = z.total_out; - inflateEnd(&z); - } - return result; + z_stream z; /* Stream information for zlib */ + int result; + + /* Fill the stream structure for zlib */ + z.next_in = (Bytef *)in_buf; + z.avail_in = (uInt)in_length; + z.total_in = in_length; + z.next_out = (Bytef *)out_buf; + z.avail_out = *out_length; + z.total_out = 0; + z.zalloc = NULL; + z.zfree = NULL; + + /* Initialize the decompression structure. Storm.dll uses zlib version 1.1.3 */ + if ((result = inflateInit(&z)) == 0) { + + /* Call zlib to decompress the data */ + result = inflate(&z, Z_FINISH); + *out_length = z.total_out; + inflateEnd(&z); + } + return result; #else - memset(out_buf, '0', *out_length); - return 0; + memset(out_buf, '0', *out_length); + return 0; #endif } @@ -157,106 +157,106 @@ int libmpq_zlib_decompress(char *out_buf, int *out_length, char *in_buf, int in_ * 1500F5F0 */ int libmpq_huff_decompress(char *out_buf, int *out_length, char *in_buf, int in_length) { - struct huffman_tree *ht = (huffman_tree *)malloc(sizeof(struct huffman_tree)); - struct huffman_input_stream *is = (huffman_input_stream *)malloc(sizeof(struct huffman_input_stream)); - struct huffman_tree_item *hi = (huffman_tree_item *)malloc(sizeof(struct huffman_tree_item)); - memset(ht, 0, sizeof(struct huffman_tree)); - memset(is, 0, sizeof(struct huffman_input_stream)); - memset(hi, 0, sizeof(struct huffman_tree_item)); - - /* Initialize input stream */ - is->bit_buf = *(unsigned long *)in_buf; - in_buf += sizeof(unsigned long); - is->in_buf = (unsigned char *)in_buf; - is->bits = 32; - - /* Initialize the Huffmann tree for decompression */ - libmpq_huff_init_tree(ht, hi, LIBMPQ_HUFF_DECOMPRESS); - - *out_length = libmpq_huff_do_decompress(ht, is, (unsigned char *)out_buf, *out_length); - - free(hi); - free(is); - free(ht); - return 0; + struct huffman_tree *ht = (huffman_tree *)malloc(sizeof(struct huffman_tree)); + struct huffman_input_stream *is = (huffman_input_stream *)malloc(sizeof(struct huffman_input_stream)); + struct huffman_tree_item *hi = (huffman_tree_item *)malloc(sizeof(struct huffman_tree_item)); + memset(ht, 0, sizeof(struct huffman_tree)); + memset(is, 0, sizeof(struct huffman_input_stream)); + memset(hi, 0, sizeof(struct huffman_tree_item)); + + /* Initialize input stream */ + is->bit_buf = *(unsigned long *)in_buf; + in_buf += sizeof(unsigned long); + is->in_buf = (unsigned char *)in_buf; + is->bits = 32; + + /* Initialize the Huffmann tree for decompression */ + libmpq_huff_init_tree(ht, hi, LIBMPQ_HUFF_DECOMPRESS); + + *out_length = libmpq_huff_do_decompress(ht, is, (unsigned char *)out_buf, *out_length); + + free(hi); + free(is); + free(ht); + return 0; } int libmpq_multi_decompress(char *out_buf, int *pout_length, char *in_buf, int in_length) { - char *temp_buf = NULL; /* Temporary storage for decompressed data */ - char *work_buf = NULL; /* Where to store decompressed data */ - int out_length = *pout_length; /* For storage number of output bytes */ - unsigned fDecompressions1; /* Decompressions applied to the block */ - unsigned fDecompressions2; /* Just another copy of decompressions applied to the block */ - int count = 0; /* Counter for every use */ - int entries = (sizeof(dcmp_table) / sizeof(decompress_table)); - int i; - - /* If the input length is the same as output, do nothing. */ - if (in_length == out_length) { - if (in_buf == out_buf) { - return 1; - } - memcpy(out_buf, in_buf, in_length); - return 1; - } - - /* Get applied compression types and decrement data length */ - fDecompressions1 = fDecompressions2 = (unsigned char)*in_buf++; - in_length--; - - /* Search decompression table type and get all types of compression */ - for (i = 0; i < entries; i++) { - /* We have to apply this decompression? */ - if (fDecompressions1 & dcmp_table[i].mask) { - count++; - } - - /* Clear this flag from temporary variable. */ - fDecompressions2 &= ~dcmp_table[i].mask; - } - - /* - * Check if there is some method unhandled - * (E.g. compressed by future versions) - */ - if (fDecompressions2 != 0) { - printf("Unknown Compression\n"); - return 0; - } - - /* If there is more than only one compression, we have to allocate extra buffer */ - if (count >= 2) { - temp_buf = (char *)malloc(out_length); - } - - /* Apply all decompressions */ - for (i = 0, count = 0; i < entries; i++) { - - /* If not used this kind of compression, skip the loop */ - if (fDecompressions1 & dcmp_table[i].mask) { - - /* If odd case, use target buffer for output, otherwise use allocated tempbuf */ - work_buf = (count++ & 1) ? temp_buf : out_buf; - out_length = *pout_length; - - /* Decompress buffer using corresponding function */ - dcmp_table[i].decompress(work_buf, &out_length, in_buf, in_length); - - /* Move output length to src length for next compression */ - in_length = out_length; - in_buf = work_buf; - } - } - - /* If output buffer is not the same like target buffer, we have to copy data */ - if (work_buf != out_buf) { - memcpy(out_buf, in_buf, out_length); - } - *pout_length = out_length; - - /* Delete temporary buffer, if necessary */ - if (temp_buf != NULL) { - free(temp_buf); - } - return 1; + char *temp_buf = NULL; /* Temporary storage for decompressed data */ + char *work_buf = NULL; /* Where to store decompressed data */ + int out_length = *pout_length; /* For storage number of output bytes */ + unsigned fDecompressions1; /* Decompressions applied to the block */ + unsigned fDecompressions2; /* Just another copy of decompressions applied to the block */ + int count = 0; /* Counter for every use */ + int entries = (sizeof(dcmp_table) / sizeof(decompress_table)); + int i; + + /* If the input length is the same as output, do nothing. */ + if (in_length == out_length) { + if (in_buf == out_buf) { + return 1; + } + memcpy(out_buf, in_buf, in_length); + return 1; + } + + /* Get applied compression types and decrement data length */ + fDecompressions1 = fDecompressions2 = (unsigned char)*in_buf++; + in_length--; + + /* Search decompression table type and get all types of compression */ + for (i = 0; i < entries; i++) { + /* We have to apply this decompression? */ + if (fDecompressions1 & dcmp_table[i].mask) { + count++; + } + + /* Clear this flag from temporary variable. */ + fDecompressions2 &= ~dcmp_table[i].mask; + } + + /* + * Check if there is some method unhandled + * (E.g. compressed by future versions) + */ + if (fDecompressions2 != 0) { + printf("Unknown Compression\n"); + return 0; + } + + /* If there is more than only one compression, we have to allocate extra buffer */ + if (count >= 2) { + temp_buf = (char *)malloc(out_length); + } + + /* Apply all decompressions */ + for (i = 0, count = 0; i < entries; i++) { + + /* If not used this kind of compression, skip the loop */ + if (fDecompressions1 & dcmp_table[i].mask) { + + /* If odd case, use target buffer for output, otherwise use allocated tempbuf */ + work_buf = (count++ & 1) ? temp_buf : out_buf; + out_length = *pout_length; + + /* Decompress buffer using corresponding function */ + dcmp_table[i].decompress(work_buf, &out_length, in_buf, in_length); + + /* Move output length to src length for next compression */ + in_length = out_length; + in_buf = work_buf; + } + } + + /* If output buffer is not the same like target buffer, we have to copy data */ + if (work_buf != out_buf) { + memcpy(out_buf, in_buf, out_length); + } + *pout_length = out_length; + + /* Delete temporary buffer, if necessary */ + if (temp_buf != NULL) { + free(temp_buf); + } + return 1; } diff --git a/contrib/extractor/libmpq/huffman.cpp b/contrib/extractor/libmpq/huffman.cpp index b63eee43e42..b126a887fd1 100644 --- a/contrib/extractor/libmpq/huffman.cpp +++ b/contrib/extractor/libmpq/huffman.cpp @@ -37,797 +37,797 @@ unsigned char table1502A630[] = { - /* Data for compression type 0x00 */ - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, - - /* Data for compression type 0x01 */ - 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05, - 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, - 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, - 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, - 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, - 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, - 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03, - 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, - 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B, - 0x00, 0x00, - - /* Data for compression type 0x02 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04, - 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02, - 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, - 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A, - 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - /* Data for compression type 0x03 */ - 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03, - 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, - 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, - 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03, - 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01, - 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, - 0x00, 0x00, - - /* Data for compression type 0x04 */ - 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - /* Data for compression type 0x05 */ - 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82, - 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37, - 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D, - 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - /* Data for compression type 0x06 */ - 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - /* Data for compression type 0x07 */ - 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - - /* Data for compression type 0x08 */ - 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10, - 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11, - 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00 + /* Data for compression type 0x00 */ + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, + + /* Data for compression type 0x01 */ + 0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05, + 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, + 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, + 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, + 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, + 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, + 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03, + 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, + 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B, + 0x00, 0x00, + + /* Data for compression type 0x02 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04, + 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02, + 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, + 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A, + 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Data for compression type 0x03 */ + 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03, + 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, + 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, + 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03, + 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01, + 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, + 0x00, 0x00, + + /* Data for compression type 0x04 */ + 0xFF, 0xFB, 0x98, 0x9A, 0x84, 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Data for compression type 0x05 */ + 0xFF, 0xF1, 0x9D, 0x9E, 0x9A, 0x9B, 0x9A, 0x97, 0x93, 0x93, 0x8C, 0x8E, 0x86, 0x88, 0x80, 0x82, + 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37, + 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D, + 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Data for compression type 0x06 */ + 0xC3, 0xCB, 0xF5, 0x41, 0xFF, 0x7B, 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBF, 0xCC, 0xF2, 0x40, 0xFD, 0x7C, 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Data for compression type 0x07 */ + 0xC3, 0xD9, 0xEF, 0x3D, 0xF9, 0x7C, 0xE9, 0x1E, 0xFD, 0xAB, 0xF1, 0x2C, 0xFC, 0x5B, 0xFE, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBD, 0xD9, 0xEC, 0x3D, 0xF5, 0x7D, 0xE8, 0x1D, 0xFB, 0xAE, 0xF0, 0x2C, 0xFB, 0x5C, 0xFF, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + /* Data for compression type 0x08 */ + 0xBA, 0xC5, 0xDA, 0x33, 0xE3, 0x6D, 0xD8, 0x18, 0xE5, 0x94, 0xDA, 0x23, 0xDF, 0x4A, 0xD1, 0x10, + 0xEE, 0xAF, 0xE4, 0x2C, 0xEA, 0x5A, 0xDE, 0x15, 0xF4, 0x87, 0xE9, 0x21, 0xF6, 0x43, 0xFC, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xB0, 0xC7, 0xD8, 0x33, 0xE3, 0x6B, 0xD6, 0x18, 0xE7, 0x95, 0xD8, 0x23, 0xDB, 0x49, 0xD0, 0x11, + 0xE9, 0xB2, 0xE2, 0x2B, 0xE8, 0x5C, 0xDD, 0x15, 0xF1, 0x87, 0xE7, 0x20, 0xF7, 0x44, 0xFF, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5F, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 }; /* Gets previous Huffman tree item (?) */ struct huffman_tree_item *libmpq_huff_get_prev_item(struct huffman_tree_item *hi, long value) { - if (PTR_INT(hi->prev) < 0) { - return PTR_NOT(hi->prev); - } - if (value < 0) { - value = hi - hi->next->prev; - } - return hi->prev + value; + if (PTR_INT(hi->prev) < 0) { + return PTR_NOT(hi->prev); + } + if (value < 0) { + value = hi - hi->next->prev; + } + return hi->prev + value; } /* 1500BC90 */ static void libmpq_huff_remove_item(struct huffman_tree_item *hi) { - struct huffman_tree_item *temp; /* EDX */ - - if (hi->next != NULL) { - temp = hi->prev; - if (PTR_INT(temp) <= 0) { - temp = PTR_NOT(temp); - } else { - temp += (hi - hi->next->prev); - } - temp->next = hi->next; - hi->next->prev = hi->prev; - hi->next = hi->prev = NULL; - } + struct huffman_tree_item *temp; /* EDX */ + + if (hi->next != NULL) { + temp = hi->prev; + if (PTR_INT(temp) <= 0) { + temp = PTR_NOT(temp); + } else { + temp += (hi - hi->next->prev); + } + temp->next = hi->next; + hi->next->prev = hi->prev; + hi->next = hi->prev = NULL; + } } static void libmpq_huff_insert_item(struct huffman_tree_item **p_item, struct huffman_tree_item *item, unsigned long where, struct huffman_tree_item *item2) { - struct huffman_tree_item *next = item->next; /* EDI - next to the first item */ - struct huffman_tree_item *prev = item->prev; /* ESI - prev to the first item */ - struct huffman_tree_item *prev2; /* Pointer to previous item */ - long next2; /* Pointer to the next item */ - - /* The same code like in mpq_huff_remove_item(); */ - if (next != 0) { /* If the first item already has next one */ - if (PTR_INT(prev) < 0) { - prev = PTR_NOT(prev); - } else { - prev += (item - next->prev); - } - - /* - * 150083C1 - * Remove the item from the tree - */ - prev->next = next; - next->prev = prev; - - /* Invalidate 'prev' and 'next' pointer */ - item->next = 0; - item->prev = 0; - } - - if (item2 == NULL) { /* EDX - If the second item is not entered, */ - item2 = PTR_PTR(&p_item[1]); /* take the first tree item */ - } - - switch (where) { - case SWITCH_ITEMS: /* Switch the two items */ - item->next = item2->next; /* item2->next (Pointer to pointer to first) */ - item->prev = item2->next->prev; - item2->next->prev = item; - item2->next = item; /* Set the first item */ - return; - case INSERT_ITEM: /* Insert as the last item */ - item->next = item2; /* Set next item (or pointer to pointer to first item) */ - item->prev = item2->prev; /* Set prev item (or last item in the tree) */ - next2 = PTR_INT(p_item[0]); /* Usually NULL */ - prev2 = item2->prev; /* Prev item to the second (or last tree item) */ - if (PTR_INT(prev2) < 0) { - prev2 = PTR_NOT(prev); - prev2->next = item; - item2->prev = item; /* Next after last item */ - return; - } - if (next2 < 0) { - next2 = item2 - item2->next->prev; - } - prev2 += next2; - prev2->next = item; - item2->prev = item; /* Set the next/last item */ - return; - default: - return; - } + struct huffman_tree_item *next = item->next; /* EDI - next to the first item */ + struct huffman_tree_item *prev = item->prev; /* ESI - prev to the first item */ + struct huffman_tree_item *prev2; /* Pointer to previous item */ + long next2; /* Pointer to the next item */ + + /* The same code like in mpq_huff_remove_item(); */ + if (next != 0) { /* If the first item already has next one */ + if (PTR_INT(prev) < 0) { + prev = PTR_NOT(prev); + } else { + prev += (item - next->prev); + } + + /* + * 150083C1 + * Remove the item from the tree + */ + prev->next = next; + next->prev = prev; + + /* Invalidate 'prev' and 'next' pointer */ + item->next = 0; + item->prev = 0; + } + + if (item2 == NULL) { /* EDX - If the second item is not entered, */ + item2 = PTR_PTR(&p_item[1]); /* take the first tree item */ + } + + switch (where) { + case SWITCH_ITEMS: /* Switch the two items */ + item->next = item2->next; /* item2->next (Pointer to pointer to first) */ + item->prev = item2->next->prev; + item2->next->prev = item; + item2->next = item; /* Set the first item */ + return; + case INSERT_ITEM: /* Insert as the last item */ + item->next = item2; /* Set next item (or pointer to pointer to first item) */ + item->prev = item2->prev; /* Set prev item (or last item in the tree) */ + next2 = PTR_INT(p_item[0]); /* Usually NULL */ + prev2 = item2->prev; /* Prev item to the second (or last tree item) */ + if (PTR_INT(prev2) < 0) { + prev2 = PTR_NOT(prev); + prev2->next = item; + item2->prev = item; /* Next after last item */ + return; + } + if (next2 < 0) { + next2 = item2 - item2->next->prev; + } + prev2 += next2; + prev2->next = item; + item2->prev = item; /* Set the next/last item */ + return; + default: + return; + } } /* Builds Huffman tree. Called with the first 8 bits loaded from input stream. */ static void libmpq_huff_build_tree(struct huffman_tree *ht, unsigned int cmp_type) { - unsigned long max_byte; /* [ESP+10] - The greatest character found in table */ - unsigned char *byte_array; /* [ESP+1C] - Pointer to unsigned char in table1502A630 */ - unsigned long i; /* egcs in linux doesn't like multiple for loops without an explicit i */ - unsigned int found; /* Thats needed to replace the goto stuff from original source :) */ - struct huffman_tree_item **p_item; /* [ESP+14] - Pointer to Huffman tree item pointer array */ - struct huffman_tree_item *child1; - - /* Loop while pointer has a negative value. */ - while (PTR_INT(ht->last) > 0) { /* ESI - Last entry */ - struct huffman_tree_item *temp; /* EAX */ - - if (ht->last->next != NULL) { /* ESI->next */ - libmpq_huff_remove_item(ht->last); - } - ht->item3058 = PTR_PTR(&ht->item3054);/* [EDI+4] */ - ht->last->prev = ht->item3058; /* EAX */ - temp = libmpq_huff_get_prev_item(PTR_PTR(&ht->item3054), PTR_INT(&ht->item3050)); - temp->next = ht->last; - ht->item3054 = ht->last; - } - - /* Clear all pointers in huffman tree item array. */ - memset(ht->items306C, 0, sizeof(ht->items306C)); - - max_byte = 0; /* Greatest character found init to zero. */ - p_item = (struct huffman_tree_item **)&ht->items306C; /* Pointer to current entry in huffman tree item pointer array */ - - /* Ensure we have low 8 bits only */ - cmp_type &= 0xFF; - byte_array = table1502A630 + cmp_type * 258; /* EDI also */ - - for (i = 0; i < 0x100; i++, p_item++) { - struct huffman_tree_item *item = ht->item3058; /* Item to be created */ - struct huffman_tree_item *p_item3 = ht->item3058; - unsigned char one_byte = byte_array[i]; - - /* Skip all the bytes which are zero. */ - if (byte_array[i] == 0) { - continue; - } - - /* If not valid pointer, take the first available item in the array. */ - if (PTR_INT(item) <= 0) { - item = &ht->items0008[ht->items++]; - } - - /* Insert this item as the top of the tree. */ - libmpq_huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL); - - item->parent = NULL; /* Invalidate child and parent */ - item->child = NULL; - *p_item = item; /* Store pointer into pointer array */ - - item->dcmp_byte = i; /* Store counter */ - item->byte_value = one_byte; /* Store byte value */ - if (one_byte >= max_byte) { - max_byte = one_byte; - continue; - } - - /* Find the first item which has byte value greater than current one byte */ - found = 0; - if (PTR_INT((p_item3 = ht->last)) > 0) {/* EDI - Pointer to the last item */ - - /* 15006AF7 */ - if (p_item3 != NULL) { - do { /* 15006AFB */ - if (p_item3->byte_value >= one_byte) { - found = 1; - break; - } - p_item3 = p_item3->prev; - } while (PTR_INT(p_item3) > 0); - } - } - - if (found == 0) { - p_item3 = NULL; - } - - /* 15006B09 */ - if (item->next != NULL) { - libmpq_huff_remove_item(item); - } - - /* 15006B15 */ - if (p_item3 == NULL) { - p_item3 = PTR_PTR(&ht->first); - } - - /* 15006B1F */ - item->next = p_item3->next; - item->prev = p_item3->next->prev; - p_item3->next->prev = item; - p_item3->next = item; - } - - /* 15006B4A */ - for (; i < 0x102; i++) { - struct huffman_tree_item **p_item2 = &ht->items306C[i]; /* EDI */ - - /* 15006B59 */ - struct huffman_tree_item *item2 = ht->item3058; /* ESI */ - if (PTR_INT(item2) <= 0) { - item2 = &ht->items0008[ht->items++]; - } - libmpq_huff_insert_item(&ht->item305C, item2, INSERT_ITEM, NULL); - - /* 15006B89 */ - item2->dcmp_byte = i; - item2->byte_value = 1; - item2->parent = NULL; - item2->child = NULL; - *p_item2++ = item2; - } - - /* 15006BAA */ - if (PTR_INT((child1 = ht->last)) > 0) { /* EDI - last item (first child to item */ - struct huffman_tree_item *child2; /* EBP */ - struct huffman_tree_item *item; /* ESI */ - - /* 15006BB8 */ - while (PTR_INT((child2 = child1->prev)) > 0) { - if (PTR_INT((item = ht->item3058)) <= 0) { - item = &ht->items0008[ht->items++]; - } - /* 15006BE3 */ - libmpq_huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL); - - /* 15006BF3 */ - item->parent = NULL; - item->child = NULL; - - /* - * EDX = child2->byte_value + child1->byte_value; - * EAX = child1->byte_value; - * ECX = max_byte; The greatest character (0xFF usually) - */ - item->byte_value = child1->byte_value + child2->byte_value; /* 0x02 */ - item->child = child1; /* Prev item in the */ - child1->parent = item; - child2->parent = item; - - /* EAX = item->byte_value; */ - if (item->byte_value >= max_byte) { - max_byte = item->byte_value; - } else { - struct huffman_tree_item *p_item2 = child2->prev; /* EDI */ - found = 0; - if (PTR_INT(p_item2) > 0) { - - /* 15006C2D */ - do { - if (p_item2->byte_value >= item->byte_value) { - found = 1; - break; - } - p_item2 = p_item2->prev; - } while (PTR_INT(p_item2) > 0); - } - if (found == 0) { - p_item2 = NULL; - } - if (item->next != 0) { - struct huffman_tree_item *temp4 = libmpq_huff_get_prev_item(item, -1); - temp4->next = item->next; /* The first item changed */ - item->next->prev = item->prev; /* First->prev changed to negative value */ - item->next = NULL; - item->prev = NULL; - } - - /* 15006C62 */ - if (p_item2 == NULL) { - p_item2 = PTR_PTR(&ht->first); - } - item->next = p_item2->next; /* Set item with 0x100 byte value */ - item->prev = p_item2->next->prev; /* Set item with 0x17 byte value */ - p_item2->next->prev = item; /* Changed prev of item with */ - p_item2->next = item; - } - - /* 15006C7B */ - if (PTR_INT((child1 = child2->prev)) <= 0) { - break; - } - } - } - - /* 15006C88 */ - ht->offs0004 = 1; + unsigned long max_byte; /* [ESP+10] - The greatest character found in table */ + unsigned char *byte_array; /* [ESP+1C] - Pointer to unsigned char in table1502A630 */ + unsigned long i; /* egcs in linux doesn't like multiple for loops without an explicit i */ + unsigned int found; /* Thats needed to replace the goto stuff from original source :) */ + struct huffman_tree_item **p_item; /* [ESP+14] - Pointer to Huffman tree item pointer array */ + struct huffman_tree_item *child1; + + /* Loop while pointer has a negative value. */ + while (PTR_INT(ht->last) > 0) { /* ESI - Last entry */ + struct huffman_tree_item *temp; /* EAX */ + + if (ht->last->next != NULL) { /* ESI->next */ + libmpq_huff_remove_item(ht->last); + } + ht->item3058 = PTR_PTR(&ht->item3054);/* [EDI+4] */ + ht->last->prev = ht->item3058; /* EAX */ + temp = libmpq_huff_get_prev_item(PTR_PTR(&ht->item3054), PTR_INT(&ht->item3050)); + temp->next = ht->last; + ht->item3054 = ht->last; + } + + /* Clear all pointers in huffman tree item array. */ + memset(ht->items306C, 0, sizeof(ht->items306C)); + + max_byte = 0; /* Greatest character found init to zero. */ + p_item = (struct huffman_tree_item **)&ht->items306C; /* Pointer to current entry in huffman tree item pointer array */ + + /* Ensure we have low 8 bits only */ + cmp_type &= 0xFF; + byte_array = table1502A630 + cmp_type * 258; /* EDI also */ + + for (i = 0; i < 0x100; i++, p_item++) { + struct huffman_tree_item *item = ht->item3058; /* Item to be created */ + struct huffman_tree_item *p_item3 = ht->item3058; + unsigned char one_byte = byte_array[i]; + + /* Skip all the bytes which are zero. */ + if (byte_array[i] == 0) { + continue; + } + + /* If not valid pointer, take the first available item in the array. */ + if (PTR_INT(item) <= 0) { + item = &ht->items0008[ht->items++]; + } + + /* Insert this item as the top of the tree. */ + libmpq_huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL); + + item->parent = NULL; /* Invalidate child and parent */ + item->child = NULL; + *p_item = item; /* Store pointer into pointer array */ + + item->dcmp_byte = i; /* Store counter */ + item->byte_value = one_byte; /* Store byte value */ + if (one_byte >= max_byte) { + max_byte = one_byte; + continue; + } + + /* Find the first item which has byte value greater than current one byte */ + found = 0; + if (PTR_INT((p_item3 = ht->last)) > 0) {/* EDI - Pointer to the last item */ + + /* 15006AF7 */ + if (p_item3 != NULL) { + do { /* 15006AFB */ + if (p_item3->byte_value >= one_byte) { + found = 1; + break; + } + p_item3 = p_item3->prev; + } while (PTR_INT(p_item3) > 0); + } + } + + if (found == 0) { + p_item3 = NULL; + } + + /* 15006B09 */ + if (item->next != NULL) { + libmpq_huff_remove_item(item); + } + + /* 15006B15 */ + if (p_item3 == NULL) { + p_item3 = PTR_PTR(&ht->first); + } + + /* 15006B1F */ + item->next = p_item3->next; + item->prev = p_item3->next->prev; + p_item3->next->prev = item; + p_item3->next = item; + } + + /* 15006B4A */ + for (; i < 0x102; i++) { + struct huffman_tree_item **p_item2 = &ht->items306C[i]; /* EDI */ + + /* 15006B59 */ + struct huffman_tree_item *item2 = ht->item3058; /* ESI */ + if (PTR_INT(item2) <= 0) { + item2 = &ht->items0008[ht->items++]; + } + libmpq_huff_insert_item(&ht->item305C, item2, INSERT_ITEM, NULL); + + /* 15006B89 */ + item2->dcmp_byte = i; + item2->byte_value = 1; + item2->parent = NULL; + item2->child = NULL; + *p_item2++ = item2; + } + + /* 15006BAA */ + if (PTR_INT((child1 = ht->last)) > 0) { /* EDI - last item (first child to item */ + struct huffman_tree_item *child2; /* EBP */ + struct huffman_tree_item *item; /* ESI */ + + /* 15006BB8 */ + while (PTR_INT((child2 = child1->prev)) > 0) { + if (PTR_INT((item = ht->item3058)) <= 0) { + item = &ht->items0008[ht->items++]; + } + /* 15006BE3 */ + libmpq_huff_insert_item(&ht->item305C, item, SWITCH_ITEMS, NULL); + + /* 15006BF3 */ + item->parent = NULL; + item->child = NULL; + + /* + * EDX = child2->byte_value + child1->byte_value; + * EAX = child1->byte_value; + * ECX = max_byte; The greatest character (0xFF usually) + */ + item->byte_value = child1->byte_value + child2->byte_value; /* 0x02 */ + item->child = child1; /* Prev item in the */ + child1->parent = item; + child2->parent = item; + + /* EAX = item->byte_value; */ + if (item->byte_value >= max_byte) { + max_byte = item->byte_value; + } else { + struct huffman_tree_item *p_item2 = child2->prev; /* EDI */ + found = 0; + if (PTR_INT(p_item2) > 0) { + + /* 15006C2D */ + do { + if (p_item2->byte_value >= item->byte_value) { + found = 1; + break; + } + p_item2 = p_item2->prev; + } while (PTR_INT(p_item2) > 0); + } + if (found == 0) { + p_item2 = NULL; + } + if (item->next != 0) { + struct huffman_tree_item *temp4 = libmpq_huff_get_prev_item(item, -1); + temp4->next = item->next; /* The first item changed */ + item->next->prev = item->prev; /* First->prev changed to negative value */ + item->next = NULL; + item->prev = NULL; + } + + /* 15006C62 */ + if (p_item2 == NULL) { + p_item2 = PTR_PTR(&ht->first); + } + item->next = p_item2->next; /* Set item with 0x100 byte value */ + item->prev = p_item2->next->prev; /* Set item with 0x17 byte value */ + p_item2->next->prev = item; /* Changed prev of item with */ + p_item2->next = item; + } + + /* 15006C7B */ + if (PTR_INT((child1 = child2->prev)) <= 0) { + break; + } + } + } + + /* 15006C88 */ + ht->offs0004 = 1; } /* Gets the whole byte from the input stream. */ static unsigned long libmpq_huff_get_8bits(struct huffman_input_stream *is) { - unsigned long one_byte; + unsigned long one_byte; - if (is->bits <= 8) { - is->bit_buf |= *(unsigned short *)is->in_buf << is->bits; - is->in_buf += sizeof(unsigned short); - is->bits += 16; - } + if (is->bits <= 8) { + is->bit_buf |= *(unsigned short *)is->in_buf << is->bits; + is->in_buf += sizeof(unsigned short); + is->bits += 16; + } - one_byte = (is->bit_buf & 0xFF); - is->bit_buf >>= 8; - is->bits -= 8; + one_byte = (is->bit_buf & 0xFF); + is->bit_buf >>= 8; + is->bits -= 8; - return one_byte; + return one_byte; } /* Gets 7 bits from the stream. */ static unsigned long libmpq_huff_get_7bits(struct huffman_input_stream *is) { - if (is->bits <= 7) { - is->bit_buf |= *(unsigned short *)is->in_buf << is->bits; - is->in_buf += sizeof(unsigned short); - is->bits += 16; - } - - /* Get 7 bits from input stream. */ - return (is->bit_buf & 0x7F); + if (is->bits <= 7) { + is->bit_buf |= *(unsigned short *)is->in_buf << is->bits; + is->in_buf += sizeof(unsigned short); + is->bits += 16; + } + + /* Get 7 bits from input stream. */ + return (is->bit_buf & 0x7F); } /* Gets one bit from input stream. */ unsigned long libmpq_huff_get_bit(struct huffman_input_stream *is) { - unsigned long bit = (is->bit_buf & 1); - - is->bit_buf >>= 1; - if (--is->bits == 0) { - is->bit_buf = *(unsigned long *)is->in_buf; - is->in_buf += sizeof(unsigned long); - is->bits = 32; - } - return bit; + unsigned long bit = (is->bit_buf & 1); + + is->bit_buf >>= 1; + if (--is->bits == 0) { + is->bit_buf = *(unsigned long *)is->in_buf; + is->in_buf += sizeof(unsigned long); + is->bits = 32; + } + return bit; } static struct huffman_tree_item *libmpq_huff_call1500E740(struct huffman_tree *ht, unsigned int value) { - struct huffman_tree_item *p_item1 = ht->item3058; /* EDX */ - struct huffman_tree_item *p_item2; /* EAX */ - struct huffman_tree_item *p_next; - struct huffman_tree_item *p_prev; - struct huffman_tree_item **pp_item; - - if (PTR_INT(p_item1) <= 0 || (p_item2 = p_item1) == NULL) { - if((p_item2 = &ht->items0008[ht->items++]) != NULL) { - p_item1 = p_item2; - } else { - p_item1 = ht->first; - } - } else { - p_item1 = p_item2; - } - - p_next = p_item1->next; - if (p_next != NULL) { - p_prev = p_item1->prev; - if (PTR_INT(p_prev) <= 0) { - p_prev = PTR_NOT(p_prev); - } else { - p_prev += (p_item1 - p_item1->next->prev); - } - - p_prev->next = p_next; - p_next->prev = p_prev; - p_item1->next = NULL; - p_item1->prev = NULL; - } - pp_item = &ht->first; /* ESI */ - if (value > 1) { - - /* ECX = ht->first->next; */ - p_item1->next = *pp_item; - p_item1->prev = (*pp_item)->prev; - - (*pp_item)->prev = p_item2; - *pp_item = p_item1; - - p_item2->parent = NULL; - p_item2->child = NULL; - } else { - p_item1->next = (struct huffman_tree_item *)pp_item; - p_item1->prev = pp_item[1]; - /* EDI = ht->item305C; */ - p_prev = pp_item[1]; /* ECX */ - if (p_prev <= 0) { - p_prev = PTR_NOT(p_prev); - p_prev->next = p_item1; - p_prev->prev = p_item2; - - p_item2->parent = NULL; - p_item2->child = NULL; - } else { - if (PTR_INT(ht->item305C) < 0) { - p_prev += (struct huffman_tree_item *)pp_item - (*pp_item)->prev; - } else { - p_prev += PTR_INT(ht->item305C); - } - - p_prev->next = p_item1; - pp_item[1] = p_item2; - p_item2->parent = NULL; - p_item2->child = NULL; - } - } - return p_item2; + struct huffman_tree_item *p_item1 = ht->item3058; /* EDX */ + struct huffman_tree_item *p_item2; /* EAX */ + struct huffman_tree_item *p_next; + struct huffman_tree_item *p_prev; + struct huffman_tree_item **pp_item; + + if (PTR_INT(p_item1) <= 0 || (p_item2 = p_item1) == NULL) { + if((p_item2 = &ht->items0008[ht->items++]) != NULL) { + p_item1 = p_item2; + } else { + p_item1 = ht->first; + } + } else { + p_item1 = p_item2; + } + + p_next = p_item1->next; + if (p_next != NULL) { + p_prev = p_item1->prev; + if (PTR_INT(p_prev) <= 0) { + p_prev = PTR_NOT(p_prev); + } else { + p_prev += (p_item1 - p_item1->next->prev); + } + + p_prev->next = p_next; + p_next->prev = p_prev; + p_item1->next = NULL; + p_item1->prev = NULL; + } + pp_item = &ht->first; /* ESI */ + if (value > 1) { + + /* ECX = ht->first->next; */ + p_item1->next = *pp_item; + p_item1->prev = (*pp_item)->prev; + + (*pp_item)->prev = p_item2; + *pp_item = p_item1; + + p_item2->parent = NULL; + p_item2->child = NULL; + } else { + p_item1->next = (struct huffman_tree_item *)pp_item; + p_item1->prev = pp_item[1]; + /* EDI = ht->item305C; */ + p_prev = pp_item[1]; /* ECX */ + if (p_prev <= 0) { + p_prev = PTR_NOT(p_prev); + p_prev->next = p_item1; + p_prev->prev = p_item2; + + p_item2->parent = NULL; + p_item2->child = NULL; + } else { + if (PTR_INT(ht->item305C) < 0) { + p_prev += (struct huffman_tree_item *)pp_item - (*pp_item)->prev; + } else { + p_prev += PTR_INT(ht->item305C); + } + + p_prev->next = p_item1; + pp_item[1] = p_item2; + p_item2->parent = NULL; + p_item2->child = NULL; + } + } + return p_item2; } static void libmpq_huff_call1500E820(struct huffman_tree *ht, struct huffman_tree_item *p_item) { - struct huffman_tree_item *p_item1; /* EDI */ - struct huffman_tree_item *p_item2 = NULL; /* EAX */ - struct huffman_tree_item *p_item3; /* EDX */ - struct huffman_tree_item *p_prev; /* EBX */ - - for (; p_item != NULL; p_item = p_item->parent) { - p_item->byte_value++; - - for (p_item1 = p_item; ; p_item1 = p_prev) { - p_prev = p_item1->prev; - if (PTR_INT(p_prev) <= 0) { - p_prev = NULL; - break; - } - if (p_prev->byte_value >= p_item->byte_value) { - break; - } - } - - if (p_item1 == p_item) { - continue; - } - - if (p_item1->next != NULL) { - p_item2 = libmpq_huff_get_prev_item(p_item1, -1); - p_item2->next = p_item1->next; - p_item1->next->prev = p_item1->prev; - p_item1->next = NULL; - p_item1->prev = NULL; - } - p_item2 = p_item->next; - p_item1->next = p_item2; - p_item1->prev = p_item2->prev; - p_item2->prev = p_item1; - p_item->next = p_item1; - if ((p_item2 = p_item1) != NULL) { - p_item2 = libmpq_huff_get_prev_item(p_item, -1); - p_item2->next = p_item->next; - p_item->next->prev = p_item->prev; - p_item->next = NULL; - p_item->prev = NULL; - } - - if (p_prev == NULL) { - p_prev = PTR_PTR(&ht->first); - } - p_item2 = p_prev->next; - p_item->next = p_item2; - p_item->prev = p_item2->prev; - p_item2->prev = p_item; - p_prev->next = p_item; - - p_item3 = p_item1->parent->child; - p_item2 = p_item->parent; - if (p_item2->child == p_item) { - p_item2->child = p_item1; - } - - if (p_item3 == p_item1) { - p_item1->parent->child = p_item; - } - - p_item2 = p_item->parent; - p_item->parent = p_item1->parent; - p_item1->parent = p_item2; - ht->offs0004++; - } + struct huffman_tree_item *p_item1; /* EDI */ + struct huffman_tree_item *p_item2 = NULL; /* EAX */ + struct huffman_tree_item *p_item3; /* EDX */ + struct huffman_tree_item *p_prev; /* EBX */ + + for (; p_item != NULL; p_item = p_item->parent) { + p_item->byte_value++; + + for (p_item1 = p_item; ; p_item1 = p_prev) { + p_prev = p_item1->prev; + if (PTR_INT(p_prev) <= 0) { + p_prev = NULL; + break; + } + if (p_prev->byte_value >= p_item->byte_value) { + break; + } + } + + if (p_item1 == p_item) { + continue; + } + + if (p_item1->next != NULL) { + p_item2 = libmpq_huff_get_prev_item(p_item1, -1); + p_item2->next = p_item1->next; + p_item1->next->prev = p_item1->prev; + p_item1->next = NULL; + p_item1->prev = NULL; + } + p_item2 = p_item->next; + p_item1->next = p_item2; + p_item1->prev = p_item2->prev; + p_item2->prev = p_item1; + p_item->next = p_item1; + if ((p_item2 = p_item1) != NULL) { + p_item2 = libmpq_huff_get_prev_item(p_item, -1); + p_item2->next = p_item->next; + p_item->next->prev = p_item->prev; + p_item->next = NULL; + p_item->prev = NULL; + } + + if (p_prev == NULL) { + p_prev = PTR_PTR(&ht->first); + } + p_item2 = p_prev->next; + p_item->next = p_item2; + p_item->prev = p_item2->prev; + p_item2->prev = p_item; + p_prev->next = p_item; + + p_item3 = p_item1->parent->child; + p_item2 = p_item->parent; + if (p_item2->child == p_item) { + p_item2->child = p_item1; + } + + if (p_item3 == p_item1) { + p_item1->parent->child = p_item; + } + + p_item2 = p_item->parent; + p_item->parent = p_item1->parent; + p_item1->parent = p_item2; + ht->offs0004++; + } } int libmpq_huff_do_decompress(struct huffman_tree *ht, struct huffman_input_stream *is, unsigned char *out_buf, unsigned int out_length) { - unsigned int n8bits; /* 8 bits loaded from input stream */ - unsigned int n7bits; /* 7 bits loaded from input stream */ - unsigned int found; /* Thats needed to replace the goto stuff from original source :) */ - unsigned int dcmp_byte = 0; - unsigned long bit_count; - struct huffman_decompress *qd; - unsigned int has_qd; /* Can we use quick decompression? */ - struct huffman_tree_item *p_item1; - struct huffman_tree_item *p_item2; - unsigned char *out_pos = out_buf; - - /* Test the output length. Must not be non zero. */ - if (out_length == 0) { - return 0; - } - - /* Get the compression type from the input stream. */ - n8bits = libmpq_huff_get_8bits(is); - - /* Build the Huffman tree */ - libmpq_huff_build_tree(ht, n8bits); - ht->cmp0 = (n8bits == 0) ? TRUE : FALSE; - - for(;;) { - n7bits = libmpq_huff_get_7bits(is); /* Get 7 bits from input stream */ - - /* - * Try to use quick decompression. Check huffman_decompress array for corresponding item. - * If found, use the result byte instead. - */ - qd = &ht->qd3474[n7bits]; - - /* If there is a quick-pass possible (ebx) */ - has_qd = (qd->offs00 >= ht->offs0004) ? TRUE : FALSE; - - /* If we can use quick decompress, use it. */ - if (has_qd) { - found = 0; - if (qd->bits > 7) { - is->bit_buf >>= 7; - is->bits -= 7; - p_item1 = qd->p_item; - found = 1; - } - if (found == 0) { - is->bit_buf >>= qd->bits; - is->bits -= qd->bits; - dcmp_byte = qd->dcmp_byte; - } - } else { - found = 1; - p_item1 = ht->first->next->prev; - if (PTR_INT(p_item1) <= 0) { - p_item1 = NULL; - } - } - - if (found == 1) { - bit_count = 0; - p_item2 = NULL; - do { - p_item1 = p_item1->child; /* Move down by one level */ - if (libmpq_huff_get_bit(is)) { /* If current bit is set, move to previous */ - p_item1 = p_item1->prev; - } - if (++bit_count == 7) { /* If we are at 7th bit, save current huffman tree item. */ - p_item2 = p_item1; - } - } while (p_item1->child != NULL); /* Walk until tree has no deeper level */ - - if (has_qd == FALSE) { - if (bit_count > 7) { - qd->offs00 = ht->offs0004; - qd->bits = bit_count; - qd->p_item = p_item2; - } else { - unsigned long index = n7bits & (0xFFFFFFFF >> (32 - bit_count)); - unsigned long add = (1 << bit_count); - - for (qd = &ht->qd3474[index]; index <= 0x7F; index += add, qd += add) { - qd->offs00 = ht->offs0004; - qd->bits = bit_count; - qd->dcmp_byte = p_item1->dcmp_byte; - } - } - } - dcmp_byte = p_item1->dcmp_byte; - } - - if (dcmp_byte == 0x101) { /* Huffman tree needs to be modified */ - n8bits = libmpq_huff_get_8bits(is); - p_item1 = (ht->last <= 0) ? NULL : ht->last; - - p_item2 = libmpq_huff_call1500E740(ht, 1); - p_item2->parent = p_item1; - p_item2->dcmp_byte = p_item1->dcmp_byte; - p_item2->byte_value = p_item1->byte_value; - ht->items306C[p_item2->dcmp_byte] = p_item2; - - p_item2 = libmpq_huff_call1500E740(ht, 1); - p_item2->parent = p_item1; - p_item2->dcmp_byte = n8bits; - p_item2->byte_value = 0; - ht->items306C[p_item2->dcmp_byte] = p_item2; - - p_item1->child = p_item2; - libmpq_huff_call1500E820(ht, p_item2); - if (ht->cmp0 == 0) { - libmpq_huff_call1500E820(ht, ht->items306C[n8bits]); - } - dcmp_byte = n8bits; - } - - if (dcmp_byte == 0x100) { - break; - } - - *out_pos++ = (unsigned char)dcmp_byte; - if (--out_length == 0) { - break; - } - if (ht->cmp0) { - libmpq_huff_call1500E820(ht, ht->items306C[dcmp_byte]); - } - } - return (out_pos - out_buf); + unsigned int n8bits; /* 8 bits loaded from input stream */ + unsigned int n7bits; /* 7 bits loaded from input stream */ + unsigned int found; /* Thats needed to replace the goto stuff from original source :) */ + unsigned int dcmp_byte = 0; + unsigned long bit_count; + struct huffman_decompress *qd; + unsigned int has_qd; /* Can we use quick decompression? */ + struct huffman_tree_item *p_item1; + struct huffman_tree_item *p_item2; + unsigned char *out_pos = out_buf; + + /* Test the output length. Must not be non zero. */ + if (out_length == 0) { + return 0; + } + + /* Get the compression type from the input stream. */ + n8bits = libmpq_huff_get_8bits(is); + + /* Build the Huffman tree */ + libmpq_huff_build_tree(ht, n8bits); + ht->cmp0 = (n8bits == 0) ? TRUE : FALSE; + + for(;;) { + n7bits = libmpq_huff_get_7bits(is); /* Get 7 bits from input stream */ + + /* + * Try to use quick decompression. Check huffman_decompress array for corresponding item. + * If found, use the result byte instead. + */ + qd = &ht->qd3474[n7bits]; + + /* If there is a quick-pass possible (ebx) */ + has_qd = (qd->offs00 >= ht->offs0004) ? TRUE : FALSE; + + /* If we can use quick decompress, use it. */ + if (has_qd) { + found = 0; + if (qd->bits > 7) { + is->bit_buf >>= 7; + is->bits -= 7; + p_item1 = qd->p_item; + found = 1; + } + if (found == 0) { + is->bit_buf >>= qd->bits; + is->bits -= qd->bits; + dcmp_byte = qd->dcmp_byte; + } + } else { + found = 1; + p_item1 = ht->first->next->prev; + if (PTR_INT(p_item1) <= 0) { + p_item1 = NULL; + } + } + + if (found == 1) { + bit_count = 0; + p_item2 = NULL; + do { + p_item1 = p_item1->child; /* Move down by one level */ + if (libmpq_huff_get_bit(is)) { /* If current bit is set, move to previous */ + p_item1 = p_item1->prev; + } + if (++bit_count == 7) { /* If we are at 7th bit, save current huffman tree item. */ + p_item2 = p_item1; + } + } while (p_item1->child != NULL); /* Walk until tree has no deeper level */ + + if (has_qd == FALSE) { + if (bit_count > 7) { + qd->offs00 = ht->offs0004; + qd->bits = bit_count; + qd->p_item = p_item2; + } else { + unsigned long index = n7bits & (0xFFFFFFFF >> (32 - bit_count)); + unsigned long add = (1 << bit_count); + + for (qd = &ht->qd3474[index]; index <= 0x7F; index += add, qd += add) { + qd->offs00 = ht->offs0004; + qd->bits = bit_count; + qd->dcmp_byte = p_item1->dcmp_byte; + } + } + } + dcmp_byte = p_item1->dcmp_byte; + } + + if (dcmp_byte == 0x101) { /* Huffman tree needs to be modified */ + n8bits = libmpq_huff_get_8bits(is); + p_item1 = (ht->last <= 0) ? NULL : ht->last; + + p_item2 = libmpq_huff_call1500E740(ht, 1); + p_item2->parent = p_item1; + p_item2->dcmp_byte = p_item1->dcmp_byte; + p_item2->byte_value = p_item1->byte_value; + ht->items306C[p_item2->dcmp_byte] = p_item2; + + p_item2 = libmpq_huff_call1500E740(ht, 1); + p_item2->parent = p_item1; + p_item2->dcmp_byte = n8bits; + p_item2->byte_value = 0; + ht->items306C[p_item2->dcmp_byte] = p_item2; + + p_item1->child = p_item2; + libmpq_huff_call1500E820(ht, p_item2); + if (ht->cmp0 == 0) { + libmpq_huff_call1500E820(ht, ht->items306C[n8bits]); + } + dcmp_byte = n8bits; + } + + if (dcmp_byte == 0x100) { + break; + } + + *out_pos++ = (unsigned char)dcmp_byte; + if (--out_length == 0) { + break; + } + if (ht->cmp0) { + libmpq_huff_call1500E820(ht, ht->items306C[dcmp_byte]); + } + } + return (out_pos - out_buf); } int libmpq_huff_init_tree(struct huffman_tree *ht, struct huffman_tree_item *hi, unsigned int cmp) { - int count; - - /* Clear links for all the items in the tree */ - for (hi = ht->items0008, count = 0x203; count != 0; hi++, count--) { - hi->next = hi->prev = NULL; - } - - ht->item3050 = NULL; - ht->item3054 = PTR_PTR(&ht->item3054); - ht->item3058 = PTR_NOT(ht->item3054); - - ht->item305C = NULL; - ht->first = PTR_PTR(&ht->first); - ht->last = PTR_NOT(ht->first); - - ht->offs0004 = 1; - ht->items = 0; - - /* Clear all huffman_decompress items. Do this only if preparing for decompression */ - if (cmp == LIBMPQ_HUFF_DECOMPRESS) { - for (count = 0; count < sizeof(ht->qd3474) / sizeof(struct huffman_decompress); count++) { - ht->qd3474[count].offs00 = 0; - } - } + int count; + + /* Clear links for all the items in the tree */ + for (hi = ht->items0008, count = 0x203; count != 0; hi++, count--) { + hi->next = hi->prev = NULL; + } + + ht->item3050 = NULL; + ht->item3054 = PTR_PTR(&ht->item3054); + ht->item3058 = PTR_NOT(ht->item3054); + + ht->item305C = NULL; + ht->first = PTR_PTR(&ht->first); + ht->last = PTR_NOT(ht->first); + + ht->offs0004 = 1; + ht->items = 0; + + /* Clear all huffman_decompress items. Do this only if preparing for decompression */ + if (cmp == LIBMPQ_HUFF_DECOMPRESS) { + for (count = 0; count < sizeof(ht->qd3474) / sizeof(struct huffman_decompress); count++) { + ht->qd3474[count].offs00 = 0; + } + } return 0; } diff --git a/contrib/extractor/libmpq/huffman.h b/contrib/extractor/libmpq/huffman.h index 1f8eae54eb4..cce32dd6718 100644 --- a/contrib/extractor/libmpq/huffman.h +++ b/contrib/extractor/libmpq/huffman.h @@ -27,32 +27,32 @@ #ifndef _HUFFMAN_H #define _HUFFMAN_H -#define PTR_NOT(ptr) (struct huffman_tree_item *)(~(unsigned long)(ptr)) -#define PTR_PTR(ptr) ((struct huffman_tree_item *)(ptr)) -#define PTR_INT(ptr) (long)(ptr) +#define PTR_NOT(ptr) (struct huffman_tree_item *)(~(unsigned long)(ptr)) +#define PTR_PTR(ptr) ((struct huffman_tree_item *)(ptr)) +#define PTR_INT(ptr) (long)(ptr) -#define INSERT_ITEM 1 -#define SWITCH_ITEMS 2 /* Switch the item1 and item2 */ +#define INSERT_ITEM 1 +#define SWITCH_ITEMS 2 /* Switch the item1 and item2 */ /* * Input stream for Huffmann decompression */ struct huffman_input_stream { - unsigned char *in_buf; /* 00 - Input data */ - unsigned long bit_buf; /* 04 - Input bit buffer */ - unsigned int bits; /* 08 - Number of bits remaining in 'byte' */ + unsigned char *in_buf; /* 00 - Input data */ + unsigned long bit_buf; /* 04 - Input bit buffer */ + unsigned int bits; /* 08 - Number of bits remaining in 'byte' */ }; /* * Huffmann tree item. */ struct huffman_tree_item { - struct huffman_tree_item *next; /* 00 - Pointer to next huffman_tree_item */ - struct huffman_tree_item *prev; /* 04 - Pointer to prev huffman_tree_item (< 0 if none) */ - unsigned long dcmp_byte; /* 08 - Index of this item in item pointer array, decompressed byte value */ - unsigned long byte_value; /* 0C - Some byte value */ - struct huffman_tree_item *parent; /* 10 - Pointer to parent huffman_tree_item (NULL if none) */ - struct huffman_tree_item *child; /* 14 - Pointer to child huffman_tree_item */ + struct huffman_tree_item *next; /* 00 - Pointer to next huffman_tree_item */ + struct huffman_tree_item *prev; /* 04 - Pointer to prev huffman_tree_item (< 0 if none) */ + unsigned long dcmp_byte; /* 08 - Index of this item in item pointer array, decompressed byte value */ + unsigned long byte_value; /* 0C - Some byte value */ + struct huffman_tree_item *parent; /* 10 - Pointer to parent huffman_tree_item (NULL if none) */ + struct huffman_tree_item *child; /* 14 - Pointer to child huffman_tree_item */ }; /* @@ -66,40 +66,40 @@ struct huffman_tree_item { * directly stores output byte to output stream. */ struct huffman_decompress { - unsigned long offs00; /* 00 - 1 if resolved */ - unsigned long bits; /* 04 - Bit count */ - union { - unsigned long dcmp_byte; /* 08 - Byte value for decompress (if bitCount <= 7) */ - struct huffman_tree_item *p_item; /* 08 - THTreeItem (if number of bits is greater than 7 */ - }; + unsigned long offs00; /* 00 - 1 if resolved */ + unsigned long bits; /* 04 - Bit count */ + union { + unsigned long dcmp_byte; /* 08 - Byte value for decompress (if bitCount <= 7) */ + struct huffman_tree_item *p_item; /* 08 - THTreeItem (if number of bits is greater than 7 */ + }; }; /* * Structure for Huffman tree. */ struct huffman_tree { - unsigned long cmp0; /* 0000 - 1 if compression type 0 */ - unsigned long offs0004; /* 0004 - Some flag */ + unsigned long cmp0; /* 0000 - 1 if compression type 0 */ + unsigned long offs0004; /* 0004 - Some flag */ - struct huffman_tree_item items0008[0x203]; /* 0008 - huffman tree items */ + struct huffman_tree_item items0008[0x203]; /* 0008 - huffman tree items */ - /* Sometimes used as huffman tree item */ - struct huffman_tree_item *item3050; /* 3050 - Always NULL (?) */ - struct huffman_tree_item *item3054; /* 3054 - Pointer to huffman_tree_item */ - struct huffman_tree_item *item3058; /* 3058 - Pointer to huffman_tree_item (< 0 if invalid) */ + /* Sometimes used as huffman tree item */ + struct huffman_tree_item *item3050; /* 3050 - Always NULL (?) */ + struct huffman_tree_item *item3054; /* 3054 - Pointer to huffman_tree_item */ + struct huffman_tree_item *item3058; /* 3058 - Pointer to huffman_tree_item (< 0 if invalid) */ - /* Sometimes used as huffman tree item */ - struct huffman_tree_item *item305C; /* 305C - Usually NULL */ - struct huffman_tree_item *first; /* 3060 - Pointer to top (first) Huffman tree item */ - struct huffman_tree_item *last; /* 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid) */ - unsigned long items; /* 3068 - Number of used huffman tree items */ + /* Sometimes used as huffman tree item */ + struct huffman_tree_item *item305C; /* 305C - Usually NULL */ + struct huffman_tree_item *first; /* 3060 - Pointer to top (first) Huffman tree item */ + struct huffman_tree_item *last; /* 3064 - Pointer to bottom (last) Huffman tree item (< 0 if invalid) */ + unsigned long items; /* 3068 - Number of used huffman tree items */ - struct huffman_tree_item *items306C[0x102]; /* 306C - huffman_tree_item pointer array */ - struct huffman_decompress qd3474[0x80]; /* 3474 - Array for quick decompression */ + struct huffman_tree_item *items306C[0x102]; /* 306C - huffman_tree_item pointer array */ + struct huffman_decompress qd3474[0x80]; /* 3474 - Array for quick decompression */ - //unsigned char table1502A630[]; /* Some table to make struct size flexible */ + //unsigned char table1502A630[]; /* Some table to make struct size flexible */ }; int libmpq_huff_init_tree(struct huffman_tree *ht, struct huffman_tree_item *hi, unsigned int cmp); int libmpq_huff_do_decompress(struct huffman_tree *ht, struct huffman_input_stream *is, unsigned char *out_buf, unsigned int out_length); -#endif /* _HUFFMAN_H */ +#endif /* _HUFFMAN_H */ diff --git a/contrib/extractor/libmpq/mpq.cpp b/contrib/extractor/libmpq/mpq.cpp index c6a5d7d7bdb..f1b262bff0f 100644 --- a/contrib/extractor/libmpq/mpq.cpp +++ b/contrib/extractor/libmpq/mpq.cpp @@ -36,9 +36,9 @@ * format: MAJOR.MINOR.PATCH */ char *libmpq_version() { - static char version[10]; - sprintf(version, "%i.%i.%i", LIBMPQ_MAJOR_VERSION, LIBMPQ_MINOR_VERSION, LIBMPQ_PATCH_VERSION); - return version; + static char version[10]; + sprintf(version, "%i.%i.%i", LIBMPQ_MAJOR_VERSION, LIBMPQ_MINOR_VERSION, LIBMPQ_PATCH_VERSION); + return version; } /* @@ -47,94 +47,94 @@ char *libmpq_version() { * table. */ int libmpq_archive_open(mpq_archive *mpq_a, unsigned char *mpq_filename) { - int fd = 0; - int rb = 0; - int ncnt = FALSE; - struct stat fileinfo; - - /* allocate memory */ - mpq_a->mpq_l = (mpq_list *)malloc(sizeof(mpq_list)); - memset(mpq_a->mpq_l, 0, sizeof(mpq_list)); - mpq_a->header = (mpq_header *)malloc(sizeof(mpq_header)); - memset(mpq_a->header, 0, sizeof(mpq_header)); - - /* Check if file exists and is readable */ - fd = _open((char *)mpq_filename, MPQ_FILE_OPEN_FLAGS); - if (fd == LIBMPQ_EFILE) { - return LIBMPQ_EFILE; - } - - /* fill the structures with informations */ - strcpy((char *)mpq_a->filename, (char *)mpq_filename); - libmpq_init_buffer(mpq_a); - mpq_a->fd = fd; - mpq_a->header->id = 0; - mpq_a->maxblockindex = 0; - mpq_a->mpq_l->mpq_files = NULL; + int fd = 0; + int rb = 0; + int ncnt = FALSE; + struct stat fileinfo; + + /* allocate memory */ + mpq_a->mpq_l = (mpq_list *)malloc(sizeof(mpq_list)); + memset(mpq_a->mpq_l, 0, sizeof(mpq_list)); + mpq_a->header = (mpq_header *)malloc(sizeof(mpq_header)); + memset(mpq_a->header, 0, sizeof(mpq_header)); + + /* Check if file exists and is readable */ + fd = _open((char *)mpq_filename, MPQ_FILE_OPEN_FLAGS); + if (fd == LIBMPQ_EFILE) { + return LIBMPQ_EFILE; + } + + /* fill the structures with informations */ + strcpy((char *)mpq_a->filename, (char *)mpq_filename); + libmpq_init_buffer(mpq_a); + mpq_a->fd = fd; + mpq_a->header->id = 0; + mpq_a->maxblockindex = 0; + mpq_a->mpq_l->mpq_files = NULL; mpq_a->mpqpos = 0; //k - while (!ncnt) { - mpq_a->header->id = 0; - #ifdef WIN32 - _lseeki64(mpq_a->fd, mpq_a->mpqpos, SEEK_SET); - #else - lseek64(mpq_a->fd, mpq_a->mpqpos, SEEK_SET); - #endif - rb = _read(mpq_a->fd, mpq_a->header, sizeof(mpq_header)); - - /* if different number of bytes read, break the loop */ - if (rb != sizeof(mpq_header)) { - return LIBMPQ_EFILE_FORMAT; - } - - /* special offset for protected MPQs */ - if (mpq_a->header->offset == LIBMPQ_HEADER_W3M) { - mpq_a->flags |= LIBMPQ_FLAG_PROTECTED; - mpq_a->header->offset = sizeof(mpq_header); - } - - /* if valid signature has been found, break the loop */ + while (!ncnt) { + mpq_a->header->id = 0; + #ifdef WIN32 + _lseeki64(mpq_a->fd, mpq_a->mpqpos, SEEK_SET); + #else + lseek64(mpq_a->fd, mpq_a->mpqpos, SEEK_SET); + #endif + rb = _read(mpq_a->fd, mpq_a->header, sizeof(mpq_header)); + + /* if different number of bytes read, break the loop */ + if (rb != sizeof(mpq_header)) { + return LIBMPQ_EFILE_FORMAT; + } + + /* special offset for protected MPQs */ + if (mpq_a->header->offset == LIBMPQ_HEADER_W3M) { + mpq_a->flags |= LIBMPQ_FLAG_PROTECTED; + mpq_a->header->offset = sizeof(mpq_header); + } + + /* if valid signature has been found, break the loop */ if (mpq_a->header->id == LIBMPQ_ID_MPQ) { ncnt = true; } /*if (mpq_a->header->id == LIBMPQ_ID_MPQ && - mpq_a->header->offset == sizeof(mpq_header) && - mpq_a->header->hashtablepos < mpq_a->header->archivesize && - mpq_a->header->blocktablepos < mpq_a->header->archivesize) { - ncnt = TRUE; - }*/ - - /* move to the next possible offset */ - if (!ncnt) { - mpq_a->mpqpos += 0x200; - } - } - - /* get the right positions of the hash table and the block table. */ - mpq_a->blocksize = (0x200 << mpq_a->header->blocksize); - fstat(mpq_a->fd, &fileinfo); - - /* Normal MPQs must have position of */ - /*if (mpq_a->header->hashtablepos + mpq_a->mpqpos < fileinfo.st_size && - mpq_a->header->blocktablepos + mpq_a->mpqpos < fileinfo.st_size) { - mpq_a->header->hashtablepos += mpq_a->mpqpos; - mpq_a->header->blocktablepos += mpq_a->mpqpos; - } else { - return LIBMPQ_EFILE_FORMAT; - }*/ - - /* Try to read and decrypt the hashtable */ - if (libmpq_read_hashtable(mpq_a) != 0) { - return LIBMPQ_EHASHTABLE; - } - - /* Try to read and decrypt the blocktable */ - if (libmpq_read_blocktable(mpq_a) != 0) { - return LIBMPQ_EBLOCKTABLE; - } - - return LIBMPQ_TOOLS_SUCCESS; + mpq_a->header->offset == sizeof(mpq_header) && + mpq_a->header->hashtablepos < mpq_a->header->archivesize && + mpq_a->header->blocktablepos < mpq_a->header->archivesize) { + ncnt = TRUE; + }*/ + + /* move to the next possible offset */ + if (!ncnt) { + mpq_a->mpqpos += 0x200; + } + } + + /* get the right positions of the hash table and the block table. */ + mpq_a->blocksize = (0x200 << mpq_a->header->blocksize); + fstat(mpq_a->fd, &fileinfo); + + /* Normal MPQs must have position of */ + /*if (mpq_a->header->hashtablepos + mpq_a->mpqpos < fileinfo.st_size && + mpq_a->header->blocktablepos + mpq_a->mpqpos < fileinfo.st_size) { + mpq_a->header->hashtablepos += mpq_a->mpqpos; + mpq_a->header->blocktablepos += mpq_a->mpqpos; + } else { + return LIBMPQ_EFILE_FORMAT; + }*/ + + /* Try to read and decrypt the hashtable */ + if (libmpq_read_hashtable(mpq_a) != 0) { + return LIBMPQ_EHASHTABLE; + } + + /* Try to read and decrypt the blocktable */ + if (libmpq_read_blocktable(mpq_a) != 0) { + return LIBMPQ_EBLOCKTABLE; + } + + return LIBMPQ_TOOLS_SUCCESS; } /* @@ -142,18 +142,18 @@ int libmpq_archive_open(mpq_archive *mpq_a, unsigned char *mpq_filename) { * mpq_open_archive(); and frees the decryption buffer. */ int libmpq_archive_close(mpq_archive *mpq_a) { - memset(mpq_a->buf, 0, sizeof(mpq_a->buf)); + memset(mpq_a->buf, 0, sizeof(mpq_a->buf)); - /* free the allocated memory. */ - free(mpq_a->header); - free(mpq_a->mpq_l); + /* free the allocated memory. */ + free(mpq_a->header); + free(mpq_a->mpq_l); - /* Check if file descriptor is valid. */ - if ((_close(mpq_a->fd)) == LIBMPQ_EFILE) { - return LIBMPQ_EFILE; - } + /* Check if file descriptor is valid. */ + if ((_close(mpq_a->fd)) == LIBMPQ_EFILE) { + return LIBMPQ_EFILE; + } - return LIBMPQ_TOOLS_SUCCESS; + return LIBMPQ_TOOLS_SUCCESS; } /* @@ -161,95 +161,95 @@ int libmpq_archive_close(mpq_archive *mpq_a) { * If an error occurs something < 0 is returned. */ int libmpq_archive_info(mpq_archive *mpq_a, unsigned int infotype) { - unsigned int filecount = 0; - unsigned int fsize = 0; - unsigned int csize = 0; - mpq_block *mpq_b_end = mpq_a->blocktable + mpq_a->header->blocktablesize; - mpq_block *mpq_b = NULL; - - switch (infotype) { - case LIBMPQ_MPQ_ARCHIVE_SIZE: - return mpq_a->header->archivesize; - case LIBMPQ_MPQ_HASHTABLE_SIZE: - return mpq_a->header->hashtablesize; - case LIBMPQ_MPQ_BLOCKTABLE_SIZE: - return mpq_a->header->blocktablesize; - case LIBMPQ_MPQ_BLOCKSIZE: - return mpq_a->blocksize; - case LIBMPQ_MPQ_NUMFILES: - for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { - filecount++; - } - return filecount; - case LIBMPQ_MPQ_COMPRESSED_SIZE: - for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { - csize += mpq_b->csize; - } - return csize; - case LIBMPQ_MPQ_UNCOMPRESSED_SIZE: - for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { - fsize += mpq_b->fsize; - } - return fsize; - default: - return LIBMPQ_TOOLS_SUCCESS; - } + unsigned int filecount = 0; + unsigned int fsize = 0; + unsigned int csize = 0; + mpq_block *mpq_b_end = mpq_a->blocktable + mpq_a->header->blocktablesize; + mpq_block *mpq_b = NULL; + + switch (infotype) { + case LIBMPQ_MPQ_ARCHIVE_SIZE: + return mpq_a->header->archivesize; + case LIBMPQ_MPQ_HASHTABLE_SIZE: + return mpq_a->header->hashtablesize; + case LIBMPQ_MPQ_BLOCKTABLE_SIZE: + return mpq_a->header->blocktablesize; + case LIBMPQ_MPQ_BLOCKSIZE: + return mpq_a->blocksize; + case LIBMPQ_MPQ_NUMFILES: + for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { + filecount++; + } + return filecount; + case LIBMPQ_MPQ_COMPRESSED_SIZE: + for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { + csize += mpq_b->csize; + } + return csize; + case LIBMPQ_MPQ_UNCOMPRESSED_SIZE: + for (mpq_b = mpq_a->blocktable; mpq_b < mpq_b_end; mpq_b++) { + fsize += mpq_b->fsize; + } + return fsize; + default: + return LIBMPQ_TOOLS_SUCCESS; + } } /* * This function returns some useful file information. */ int libmpq_file_info(mpq_archive *mpq_a, unsigned int infotype, const unsigned int number) { - int blockindex = number; //-1; - int i = 0; - mpq_block *mpq_b = NULL; - mpq_hash *mpq_h = NULL; - - /* check if given number is not out of range */ - if (number < 1 || number > mpq_a->header->blocktablesize) { - return LIBMPQ_EINV_RANGE; - } - - /* search for correct hashtable */ - /*for (i = 0; i < mpq_a->header->hashtablesize; i++) { - if ((number - 1) == (mpq_a->hashtable[i]).blockindex) { - blockindex = (mpq_a->hashtable[i]).blockindex; - mpq_h = &(mpq_a->hashtable[i]); - break; - } - }*/ - - /* check if file was found */ - /*if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) { - return LIBMPQ_EFILE_NOT_FOUND; - }*/ - - /* check if sizes are correct */ - mpq_b = mpq_a->blocktable + blockindex; - if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) { - return LIBMPQ_EFILE_CORRUPT; - } - - /* check if file exists */ - if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) { - return LIBMPQ_EFILE_NOT_FOUND; - } - - switch (infotype) { - case LIBMPQ_FILE_COMPRESSED_SIZE: - return mpq_b->csize; - case LIBMPQ_FILE_UNCOMPRESSED_SIZE: - return mpq_b->fsize; - case LIBMPQ_FILE_COMPRESSION_TYPE: - if (mpq_b->flags & LIBMPQ_FILE_COMPRESS_PKWARE) { - return LIBMPQ_FILE_COMPRESS_PKWARE; - } - if (mpq_b->flags & LIBMPQ_FILE_COMPRESS_MULTI) { - return LIBMPQ_FILE_COMPRESS_MULTI; - } - default: - return LIBMPQ_TOOLS_SUCCESS; - } + int blockindex = number; //-1; + int i = 0; + mpq_block *mpq_b = NULL; + mpq_hash *mpq_h = NULL; + + /* check if given number is not out of range */ + if (number < 1 || number > mpq_a->header->blocktablesize) { + return LIBMPQ_EINV_RANGE; + } + + /* search for correct hashtable */ + /*for (i = 0; i < mpq_a->header->hashtablesize; i++) { + if ((number - 1) == (mpq_a->hashtable[i]).blockindex) { + blockindex = (mpq_a->hashtable[i]).blockindex; + mpq_h = &(mpq_a->hashtable[i]); + break; + } + }*/ + + /* check if file was found */ + /*if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) { + return LIBMPQ_EFILE_NOT_FOUND; + }*/ + + /* check if sizes are correct */ + mpq_b = mpq_a->blocktable + blockindex; + if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) { + return LIBMPQ_EFILE_CORRUPT; + } + + /* check if file exists */ + if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) { + return LIBMPQ_EFILE_NOT_FOUND; + } + + switch (infotype) { + case LIBMPQ_FILE_COMPRESSED_SIZE: + return mpq_b->csize; + case LIBMPQ_FILE_UNCOMPRESSED_SIZE: + return mpq_b->fsize; + case LIBMPQ_FILE_COMPRESSION_TYPE: + if (mpq_b->flags & LIBMPQ_FILE_COMPRESS_PKWARE) { + return LIBMPQ_FILE_COMPRESS_PKWARE; + } + if (mpq_b->flags & LIBMPQ_FILE_COMPRESS_MULTI) { + return LIBMPQ_FILE_COMPRESS_MULTI; + } + default: + return LIBMPQ_TOOLS_SUCCESS; + } } /* @@ -259,17 +259,17 @@ int libmpq_file_info(mpq_archive *mpq_a, unsigned int infotype, const unsigned i * returns NULL. */ char *libmpq_file_name(mpq_archive *mpq_a, const int number) { - static char tempfile[PATH_MAX]; + static char tempfile[PATH_MAX]; - /* check if we are in the range of available files. */ - if (number > libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) || number < 1) { - return NULL; - } + /* check if we are in the range of available files. */ + if (number > libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) || number < 1) { + return NULL; + } - /* this is safe because we built a fallback filelist, if something was wrong. */ - sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[number - 1], number); + /* this is safe because we built a fallback filelist, if something was wrong. */ + sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[number - 1], number); - return tempfile; + return tempfile; } /* @@ -277,20 +277,20 @@ char *libmpq_file_name(mpq_archive *mpq_a, const int number) { * filename. */ int libmpq_file_number(mpq_archive *mpq_a, const char *name) { - int i; - char tempfile[PATH_MAX]; + int i; + char tempfile[PATH_MAX]; - for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) { - sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i + 1); - if (strncmp(tempfile, name, strlen(name)) == 0) { + for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) { + sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i + 1); + if (strncmp(tempfile, name, strlen(name)) == 0) { - /* if file found return the number */ - return i + 1; - } - } + /* if file found return the number */ + return i + 1; + } + } - /* if no matching entry found return LIBMPQ_EFILE_NOT_FOUND */ - return LIBMPQ_EFILE_NOT_FOUND; + /* if no matching entry found return LIBMPQ_EFILE_NOT_FOUND */ + return LIBMPQ_EFILE_NOT_FOUND; } /* @@ -299,39 +299,39 @@ int libmpq_file_number(mpq_archive *mpq_a, const char *name) { * it returns 0, otherwise LIBMPQ_EFILE_NOT_FOUND. */ int libmpq_file_check(mpq_archive *mpq_a, void *file, int type) { - int found = 0; - int i; - char tempfile[PATH_MAX]; - - switch (type) { - case LIBMPQ_FILE_TYPE_INT: - - /* check if we are in the range of available files. */ - if (*(int *)file > libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) || *(int *)file < 1) { - return LIBMPQ_EFILE_NOT_FOUND; - } else { - return LIBMPQ_TOOLS_SUCCESS; - } - case LIBMPQ_FILE_TYPE_CHAR: - for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) { - sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i); - if (strncmp(tempfile, (char *)file, strlen((char *)file)) == 0) { - - /* if file found break */ - found = 1; - break; - } - } - - /* if a file was found return 0 */ - if (found == 1) { - return LIBMPQ_TOOLS_SUCCESS; - } else { - return LIBMPQ_EFILE_NOT_FOUND; - } - default: - return LIBMPQ_TOOLS_SUCCESS; - } + int found = 0; + int i; + char tempfile[PATH_MAX]; + + switch (type) { + case LIBMPQ_FILE_TYPE_INT: + + /* check if we are in the range of available files. */ + if (*(int *)file > libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES) || *(int *)file < 1) { + return LIBMPQ_EFILE_NOT_FOUND; + } else { + return LIBMPQ_TOOLS_SUCCESS; + } + case LIBMPQ_FILE_TYPE_CHAR: + for (i = 0; mpq_a->mpq_l->mpq_files[i]; i++) { + sprintf(tempfile, (char *)mpq_a->mpq_l->mpq_files[i], i); + if (strncmp(tempfile, (char *)file, strlen((char *)file)) == 0) { + + /* if file found break */ + found = 1; + break; + } + } + + /* if a file was found return 0 */ + if (found == 1) { + return LIBMPQ_TOOLS_SUCCESS; + } else { + return LIBMPQ_EFILE_NOT_FOUND; + } + default: + return LIBMPQ_TOOLS_SUCCESS; + } } /* @@ -339,102 +339,102 @@ int libmpq_file_check(mpq_archive *mpq_a, void *file, int type) { * by the given number. */ int libmpq_file_extract(mpq_archive *mpq_a, const int number, const char *filename) { - int blockindex = number; //-1; - int fd = 0; - int i = 0; - char buffer[0x1000]; - //char tempfile[PATH_MAX]; - unsigned int transferred = 1; - mpq_file *mpq_f = NULL; - mpq_block *mpq_b = NULL; - mpq_hash *mpq_h = NULL; - -/* if (number < 1 || number > mpq_a->header->blocktablesize) { - return LIBMPQ_EINV_RANGE; - }*/ + int blockindex = number; //-1; + int fd = 0; + int i = 0; + char buffer[0x1000]; + //char tempfile[PATH_MAX]; + unsigned int transferred = 1; + mpq_file *mpq_f = NULL; + mpq_block *mpq_b = NULL; + mpq_hash *mpq_h = NULL; + +/* if (number < 1 || number > mpq_a->header->blocktablesize) { + return LIBMPQ_EINV_RANGE; + }*/ /* - sprintf(tempfile, libmpq_file_name(mpq_a, number)); + sprintf(tempfile, libmpq_file_name(mpq_a, number)); */ - /* check if mpq_f->filename could be written here. */ - fd = _open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644); - if (fd == LIBMPQ_EFILE) { - return LIBMPQ_EFILE; - } - - /* search for correct hashtable */ - /*for (i = 0; i < mpq_a->header->hashtablesize; i++) { - if ((number - 1) == (mpq_a->hashtable[i]).blockindex) { - blockindex = (mpq_a->hashtable[i]).blockindex; - mpq_h = &(mpq_a->hashtable[i]); - break; - } - }*/ - - /* check if file was found */ - if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) { - return LIBMPQ_EFILE_NOT_FOUND; - } - - /* check if sizes are correct */ - mpq_b = mpq_a->blocktable + blockindex; - if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) { - return LIBMPQ_EFILE_CORRUPT; - } - - /* check if file exists */ - if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) { - return LIBMPQ_EFILE_NOT_FOUND; - } - - /* allocate memory for file structure */ - mpq_f = (mpq_file *)malloc(sizeof(mpq_file)); - if (!mpq_f) { - return LIBMPQ_EALLOCMEM; - } - - /* initialize file structure */ - memset(mpq_f, 0, sizeof(mpq_file)); - mpq_f->fd = fd; - mpq_f->mpq_b = mpq_b; - mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize; - mpq_f->mpq_h = mpq_h; - mpq_f->accessed = FALSE; - mpq_f->blockposloaded = FALSE; - sprintf((char *)mpq_f->filename, filename); - - /* allocate buffers for decompression. */ - if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { - - /* - * Allocate buffer for block positions. At the begin of file are stored - * unsigned ints holding positions of each block relative from begin of - * file in the archive. - */ - if ((mpq_f->blockpos = (unsigned int *)malloc(sizeof(int) * mpq_f->nblocks + 1)) == NULL) { - return LIBMPQ_EALLOCMEM; - } - } - - while (transferred > 0) { - transferred = libmpq_file_read_file(mpq_a, mpq_f, mpq_f->filepos, buffer, sizeof(buffer)); - if (transferred == 0) { - break; - } else { - mpq_f->accessed = TRUE; - mpq_f->filepos += transferred; - } - - transferred = _write(mpq_f->fd, buffer, transferred); - if (transferred == 0) { - break; - } - } - - _close(fd); - - /* freeing the file structure */ - free(mpq_f); - return LIBMPQ_TOOLS_SUCCESS; + /* check if mpq_f->filename could be written here. */ + fd = _open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644); + if (fd == LIBMPQ_EFILE) { + return LIBMPQ_EFILE; + } + + /* search for correct hashtable */ + /*for (i = 0; i < mpq_a->header->hashtablesize; i++) { + if ((number - 1) == (mpq_a->hashtable[i]).blockindex) { + blockindex = (mpq_a->hashtable[i]).blockindex; + mpq_h = &(mpq_a->hashtable[i]); + break; + } + }*/ + + /* check if file was found */ + if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) { + return LIBMPQ_EFILE_NOT_FOUND; + } + + /* check if sizes are correct */ + mpq_b = mpq_a->blocktable + blockindex; + if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) { + return LIBMPQ_EFILE_CORRUPT; + } + + /* check if file exists */ + if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) { + return LIBMPQ_EFILE_NOT_FOUND; + } + + /* allocate memory for file structure */ + mpq_f = (mpq_file *)malloc(sizeof(mpq_file)); + if (!mpq_f) { + return LIBMPQ_EALLOCMEM; + } + + /* initialize file structure */ + memset(mpq_f, 0, sizeof(mpq_file)); + mpq_f->fd = fd; + mpq_f->mpq_b = mpq_b; + mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize; + mpq_f->mpq_h = mpq_h; + mpq_f->accessed = FALSE; + mpq_f->blockposloaded = FALSE; + sprintf((char *)mpq_f->filename, filename); + + /* allocate buffers for decompression. */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { + + /* + * Allocate buffer for block positions. At the begin of file are stored + * unsigned ints holding positions of each block relative from begin of + * file in the archive. + */ + if ((mpq_f->blockpos = (unsigned int *)malloc(sizeof(int) * mpq_f->nblocks + 1)) == NULL) { + return LIBMPQ_EALLOCMEM; + } + } + + while (transferred > 0) { + transferred = libmpq_file_read_file(mpq_a, mpq_f, mpq_f->filepos, buffer, sizeof(buffer)); + if (transferred == 0) { + break; + } else { + mpq_f->accessed = TRUE; + mpq_f->filepos += transferred; + } + + transferred = _write(mpq_f->fd, buffer, transferred); + if (transferred == 0) { + break; + } + } + + _close(fd); + + /* freeing the file structure */ + free(mpq_f); + return LIBMPQ_TOOLS_SUCCESS; } /* @@ -444,183 +444,183 @@ int libmpq_file_extract(mpq_archive *mpq_a, const int number, const char *filena */ int libmpq_listfile_open(mpq_archive *mpq_a, char file[PATH_MAX]) { - FILE *fp; - //char **filelist; - int i = 0; - //int fl_count; - //int fl_size; - int fl_count_fb; - int fl_size_fb; - int result = LIBMPQ_TOOLS_SUCCESS; - struct stat statbuf; - - /* get file status */ - if (stat(file, &statbuf) < 0) { - result = LIBMPQ_CONF_EFILE_NOT_FOUND; - } - - /* check if file is a filename or directory */ - /*if (S_ISDIR(statbuf.st_mode)) { - - // allocate memory for the file list - filelist = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *)); - fl_count = 0; - fl_size = LIBMPQ_CONF_FL_INCREMENT; - - // check if it is a valid listfile - if (libmpq_detect_listfile_rec(file, &filelist, &fl_count, &fl_size)) { - filelist == NULL; - } - - filelist[fl_count] = NULL; - - // return if no listfile was found - if (filelist == NULL) { - result = LIBMPQ_CONF_EFILE_NOT_FOUND; - } - - for (i = 0; filelist[i]; i++) { - if ((fp = fopen(filelist[i], "r")) != NULL ) { - result = libmpq_read_listfile(mpq_a, fp); - fclose(fp); - } - } - - // freeing the listfile struct - libmpq_free_listfile(filelist); - }*/ - - /* if file is a regular file use it */ - //if (S_ISREG(statbuf.st_mode)) { - - /* if specific listfile was forced. */ - if ((fp = fopen(file, "r")) != NULL ) { - result = libmpq_read_listfile(mpq_a, fp); - fclose(fp); - } else { - result = LIBMPQ_CONF_EFILE_OPEN; - } - //} - - /* if error occured we need to create a fallback filelist. */ - if (mpq_a->mpq_l->mpq_files == NULL) { - - /* allocate memory for the file list */ - mpq_a->mpq_l->mpq_files = (unsigned char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *)); - fl_count_fb = 0; - fl_size_fb = LIBMPQ_CONF_FL_INCREMENT; - - for (i = 0; i < libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES); i++) { - - /* set the next filelist entry to a copy of the file */ - mpq_a->mpq_l->mpq_files[fl_count_fb++] = (unsigned char *)_strdup("file%06lu.xxx"); - - /* increase the array size */ - if (fl_count_fb == fl_size_fb) { - mpq_a->mpq_l->mpq_files = (unsigned char **)realloc(mpq_a->mpq_l->mpq_files, (fl_size_fb + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *)); - fl_size_fb += LIBMPQ_CONF_FL_INCREMENT; - } - } - mpq_a->mpq_l->mpq_files[fl_count_fb] = NULL; - - /* if no error occurs and no listfile was assigned, we think there was no matching listfile. */ - if (result == 0) { - result = LIBMPQ_CONF_EFILE_NOT_FOUND; - } - } - - return result; + FILE *fp; + //char **filelist; + int i = 0; + //int fl_count; + //int fl_size; + int fl_count_fb; + int fl_size_fb; + int result = LIBMPQ_TOOLS_SUCCESS; + struct stat statbuf; + + /* get file status */ + if (stat(file, &statbuf) < 0) { + result = LIBMPQ_CONF_EFILE_NOT_FOUND; + } + + /* check if file is a filename or directory */ + /*if (S_ISDIR(statbuf.st_mode)) { + + // allocate memory for the file list + filelist = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *)); + fl_count = 0; + fl_size = LIBMPQ_CONF_FL_INCREMENT; + + // check if it is a valid listfile + if (libmpq_detect_listfile_rec(file, &filelist, &fl_count, &fl_size)) { + filelist == NULL; + } + + filelist[fl_count] = NULL; + + // return if no listfile was found + if (filelist == NULL) { + result = LIBMPQ_CONF_EFILE_NOT_FOUND; + } + + for (i = 0; filelist[i]; i++) { + if ((fp = fopen(filelist[i], "r")) != NULL ) { + result = libmpq_read_listfile(mpq_a, fp); + fclose(fp); + } + } + + // freeing the listfile struct + libmpq_free_listfile(filelist); + }*/ + + /* if file is a regular file use it */ + //if (S_ISREG(statbuf.st_mode)) { + + /* if specific listfile was forced. */ + if ((fp = fopen(file, "r")) != NULL ) { + result = libmpq_read_listfile(mpq_a, fp); + fclose(fp); + } else { + result = LIBMPQ_CONF_EFILE_OPEN; + } + //} + + /* if error occured we need to create a fallback filelist. */ + if (mpq_a->mpq_l->mpq_files == NULL) { + + /* allocate memory for the file list */ + mpq_a->mpq_l->mpq_files = (unsigned char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *)); + fl_count_fb = 0; + fl_size_fb = LIBMPQ_CONF_FL_INCREMENT; + + for (i = 0; i < libmpq_archive_info(mpq_a, LIBMPQ_MPQ_NUMFILES); i++) { + + /* set the next filelist entry to a copy of the file */ + mpq_a->mpq_l->mpq_files[fl_count_fb++] = (unsigned char *)_strdup("file%06lu.xxx"); + + /* increase the array size */ + if (fl_count_fb == fl_size_fb) { + mpq_a->mpq_l->mpq_files = (unsigned char **)realloc(mpq_a->mpq_l->mpq_files, (fl_size_fb + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *)); + fl_size_fb += LIBMPQ_CONF_FL_INCREMENT; + } + } + mpq_a->mpq_l->mpq_files[fl_count_fb] = NULL; + + /* if no error occurs and no listfile was assigned, we think there was no matching listfile. */ + if (result == 0) { + result = LIBMPQ_CONF_EFILE_NOT_FOUND; + } + } + + return result; } /* * This function frees the allocated memory for the listfile. */ int libmpq_listfile_close(mpq_archive *mpq_a) { - int i = 0; - - /* safety check if we really have a filelist. */ - if (mpq_a->mpq_l->mpq_files != NULL) { - /* freeing the filelist */ - while (mpq_a->mpq_l->mpq_files[i]) { - free(mpq_a->mpq_l->mpq_files[i++]); - } - free(mpq_a->mpq_l->mpq_files); - } + int i = 0; + + /* safety check if we really have a filelist. */ + if (mpq_a->mpq_l->mpq_files != NULL) { + /* freeing the filelist */ + while (mpq_a->mpq_l->mpq_files[i]) { + free(mpq_a->mpq_l->mpq_files[i++]); + } + free(mpq_a->mpq_l->mpq_files); + } return 0; } int libmpq_file_getdata(mpq_archive *mpq_a, mpq_hash mpq_h, const int number, unsigned char *dest) { - int blockindex = number; //-1; - int i = 0; - mpq_file *mpq_f = NULL; - mpq_block *mpq_b = NULL; - int success = 0; - - /*if (number < 1 || number > mpq_a->header->blocktablesize) { - return LIBMPQ_EINV_RANGE; - }*/ - - /* search for correct hashtable */ - /*for (i = 0; i < mpq_a->header->hashtablesize; i++) { - if ((number - 1) == (mpq_a->hashtable[i]).blockindex) { - blockindex = (mpq_a->hashtable[i]).blockindex; - mpq_h = &(mpq_a->hashtable[i]); - break; - } - }*/ - - /* check if file was found */ - if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) { - return LIBMPQ_EFILE_NOT_FOUND; - } - - /* check if sizes are correct */ - mpq_b = mpq_a->blocktable + blockindex; - if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) { - return LIBMPQ_EFILE_CORRUPT; - } - - /* check if file exists */ - if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) { - return LIBMPQ_EFILE_NOT_FOUND; - } - - /* allocate memory for file structure */ - mpq_f = (mpq_file*)malloc(sizeof(mpq_file)); - if (!mpq_f) { - return LIBMPQ_EALLOCMEM; - } - - /* initialize file structure */ - memset(mpq_f, 0, sizeof(mpq_file)); - mpq_f->mpq_b = mpq_b; - mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize; - mpq_f->mpq_h = &mpq_h; - mpq_f->accessed = FALSE; - mpq_f->blockposloaded = FALSE; - - /* allocate buffers for decompression. */ - if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { - - /* - * Allocate buffer for block positions. At the begin of file are stored - * unsigned ints holding positions of each block relative from begin of - * file in the archive. - */ - if ((mpq_f->blockpos = (unsigned int*)malloc(sizeof(int) * (mpq_f->nblocks + 1))) == NULL) { - return LIBMPQ_EALLOCMEM; - } - } + int blockindex = number; //-1; + int i = 0; + mpq_file *mpq_f = NULL; + mpq_block *mpq_b = NULL; + int success = 0; + + /*if (number < 1 || number > mpq_a->header->blocktablesize) { + return LIBMPQ_EINV_RANGE; + }*/ + + /* search for correct hashtable */ + /*for (i = 0; i < mpq_a->header->hashtablesize; i++) { + if ((number - 1) == (mpq_a->hashtable[i]).blockindex) { + blockindex = (mpq_a->hashtable[i]).blockindex; + mpq_h = &(mpq_a->hashtable[i]); + break; + } + }*/ + + /* check if file was found */ + if (blockindex == -1 || blockindex > mpq_a->header->blocktablesize) { + return LIBMPQ_EFILE_NOT_FOUND; + } + + /* check if sizes are correct */ + mpq_b = mpq_a->blocktable + blockindex; + if (mpq_b->filepos > (mpq_a->header->archivesize + mpq_a->mpqpos) || mpq_b->csize > mpq_a->header->archivesize) { + return LIBMPQ_EFILE_CORRUPT; + } + + /* check if file exists */ + if ((mpq_b->flags & LIBMPQ_FILE_EXISTS) == 0) { + return LIBMPQ_EFILE_NOT_FOUND; + } + + /* allocate memory for file structure */ + mpq_f = (mpq_file*)malloc(sizeof(mpq_file)); + if (!mpq_f) { + return LIBMPQ_EALLOCMEM; + } + + /* initialize file structure */ + memset(mpq_f, 0, sizeof(mpq_file)); + mpq_f->mpq_b = mpq_b; + mpq_f->nblocks = (mpq_f->mpq_b->fsize + mpq_a->blocksize - 1) / mpq_a->blocksize; + mpq_f->mpq_h = &mpq_h; + mpq_f->accessed = FALSE; + mpq_f->blockposloaded = FALSE; + + /* allocate buffers for decompression. */ + if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { + + /* + * Allocate buffer for block positions. At the begin of file are stored + * unsigned ints holding positions of each block relative from begin of + * file in the archive. + */ + if ((mpq_f->blockpos = (unsigned int*)malloc(sizeof(int) * (mpq_f->nblocks + 1))) == NULL) { + return LIBMPQ_EALLOCMEM; + } + } if(libmpq_file_read_file(mpq_a, mpq_f, 0, (char*)dest, mpq_b->fsize) == mpq_b->fsize) success = 1; if (mpq_f->mpq_b->flags & LIBMPQ_FILE_COMPRESSED) { // Free buffer for block positions - - free(mpq_f->blockpos); - } - /* freeing the file structure */ - free(mpq_f); - return success?LIBMPQ_TOOLS_SUCCESS:LIBMPQ_EFILE_CORRUPT; + + free(mpq_f->blockpos); + } + /* freeing the file structure */ + free(mpq_f); + return success?LIBMPQ_TOOLS_SUCCESS:LIBMPQ_EFILE_CORRUPT; } diff --git a/contrib/extractor/libmpq/mpq.h b/contrib/extractor/libmpq/mpq.h index 55b72ad75a9..58eef6bead2 100644 --- a/contrib/extractor/libmpq/mpq.h +++ b/contrib/extractor/libmpq/mpq.h @@ -33,61 +33,61 @@ #include <limits.h> #ifndef PATH_MAX - #define PATH_MAX 260 + #define PATH_MAX 260 #endif -#define LIBMPQ_MAJOR_VERSION 0 /* Major version number... maybe sometimes we reach version 1 :) */ -#define LIBMPQ_MINOR_VERSION 3 /* Minor version number - increased only for small changes */ -#define LIBMPQ_PATCH_VERSION 0 /* Patchlevel - changed on bugfixes etc... */ - -#define LIBMPQ_TOOLS_SUCCESS 0 /* return value for all functions which success */ -#define LIBMPQ_TOOLS_BUFSIZE 0x500 /* buffer size for the decryption engine */ - -#define LIBMPQ_EFILE -1 /* error on file operation */ -#define LIBMPQ_EFILE_FORMAT -2 /* bad file format */ -#define LIBMPQ_EFILE_CORRUPT -3 /* file corrupt */ -#define LIBMPQ_EFILE_NOT_FOUND -4 /* file in archive not found */ -#define LIBMPQ_EFILE_READ -5 /* Read error in archive */ -#define LIBMPQ_EALLOCMEM -6 /* maybe not enough memory? :) */ -#define LIBMPQ_EFREEMEM -7 /* can not free memory */ -#define LIBMPQ_EINV_RANGE -8 /* Given filenumber is out of range */ -#define LIBMPQ_EHASHTABLE -9 /* error in reading hashtable */ -#define LIBMPQ_EBLOCKTABLE -10 /* error in reading blocktable */ - -#define LIBMPQ_ID_MPQ 0x1A51504D /* MPQ archive header ID ('MPQ\x1A') */ -#define LIBMPQ_HEADER_W3M 0x6D9E4B86 /* special value used by W3M Map Protector */ -#define LIBMPQ_FLAG_PROTECTED 0x00000002 /* Set on protected MPQs (like W3M maps) */ -#define LIBMPQ_HASH_ENTRY_DELETED 0xFFFFFFFE /* Block index for deleted hash entry */ - -#define LIBMPQ_FILE_COMPRESS_PKWARE 0x00000100 /* Compression made by PKWARE Data Compression Library */ -#define LIBMPQ_FILE_COMPRESS_MULTI 0x00000200 /* Multiple compressions */ -#define LIBMPQ_FILE_COMPRESSED 0x0000FF00 /* File is compressed */ -#define LIBMPQ_FILE_EXISTS 0x80000000 /* Set if file exists, reset when the file was deleted */ -#define LIBMPQ_FILE_ENCRYPTED 0x00010000 /* Indicates whether file is encrypted */ +#define LIBMPQ_MAJOR_VERSION 0 /* Major version number... maybe sometimes we reach version 1 :) */ +#define LIBMPQ_MINOR_VERSION 3 /* Minor version number - increased only for small changes */ +#define LIBMPQ_PATCH_VERSION 0 /* Patchlevel - changed on bugfixes etc... */ + +#define LIBMPQ_TOOLS_SUCCESS 0 /* return value for all functions which success */ +#define LIBMPQ_TOOLS_BUFSIZE 0x500 /* buffer size for the decryption engine */ + +#define LIBMPQ_EFILE -1 /* error on file operation */ +#define LIBMPQ_EFILE_FORMAT -2 /* bad file format */ +#define LIBMPQ_EFILE_CORRUPT -3 /* file corrupt */ +#define LIBMPQ_EFILE_NOT_FOUND -4 /* file in archive not found */ +#define LIBMPQ_EFILE_READ -5 /* Read error in archive */ +#define LIBMPQ_EALLOCMEM -6 /* maybe not enough memory? :) */ +#define LIBMPQ_EFREEMEM -7 /* can not free memory */ +#define LIBMPQ_EINV_RANGE -8 /* Given filenumber is out of range */ +#define LIBMPQ_EHASHTABLE -9 /* error in reading hashtable */ +#define LIBMPQ_EBLOCKTABLE -10 /* error in reading blocktable */ + +#define LIBMPQ_ID_MPQ 0x1A51504D /* MPQ archive header ID ('MPQ\x1A') */ +#define LIBMPQ_HEADER_W3M 0x6D9E4B86 /* special value used by W3M Map Protector */ +#define LIBMPQ_FLAG_PROTECTED 0x00000002 /* Set on protected MPQs (like W3M maps) */ +#define LIBMPQ_HASH_ENTRY_DELETED 0xFFFFFFFE /* Block index for deleted hash entry */ + +#define LIBMPQ_FILE_COMPRESS_PKWARE 0x00000100 /* Compression made by PKWARE Data Compression Library */ +#define LIBMPQ_FILE_COMPRESS_MULTI 0x00000200 /* Multiple compressions */ +#define LIBMPQ_FILE_COMPRESSED 0x0000FF00 /* File is compressed */ +#define LIBMPQ_FILE_EXISTS 0x80000000 /* Set if file exists, reset when the file was deleted */ +#define LIBMPQ_FILE_ENCRYPTED 0x00010000 /* Indicates whether file is encrypted */ #define LIBMPQ_FILE_HAS_METADATA 0x04000000 -#define LIBMPQ_FILE_COMPRESSED_SIZE 1 /* MPQ compressed filesize of given file */ -#define LIBMPQ_FILE_UNCOMPRESSED_SIZE 2 /* MPQ uncompressed filesize of given file */ -#define LIBMPQ_FILE_COMPRESSION_TYPE 3 /* MPQ compression type of given file */ -#define LIBMPQ_FILE_TYPE_INT 4 /* file is given by number */ -#define LIBMPQ_FILE_TYPE_CHAR 5 /* file is given by name */ +#define LIBMPQ_FILE_COMPRESSED_SIZE 1 /* MPQ compressed filesize of given file */ +#define LIBMPQ_FILE_UNCOMPRESSED_SIZE 2 /* MPQ uncompressed filesize of given file */ +#define LIBMPQ_FILE_COMPRESSION_TYPE 3 /* MPQ compression type of given file */ +#define LIBMPQ_FILE_TYPE_INT 4 /* file is given by number */ +#define LIBMPQ_FILE_TYPE_CHAR 5 /* file is given by name */ -#define LIBMPQ_MPQ_ARCHIVE_SIZE 1 /* MPQ archive size */ -#define LIBMPQ_MPQ_HASHTABLE_SIZE 2 /* MPQ archive hashtable size */ -#define LIBMPQ_MPQ_BLOCKTABLE_SIZE 3 /* MPQ archive blocktable size */ -#define LIBMPQ_MPQ_BLOCKSIZE 4 /* MPQ archive blocksize */ -#define LIBMPQ_MPQ_NUMFILES 5 /* Number of files in the MPQ archive */ -#define LIBMPQ_MPQ_COMPRESSED_SIZE 6 /* Compressed archive size */ -#define LIBMPQ_MPQ_UNCOMPRESSED_SIZE 7 /* Uncompressed archive size */ +#define LIBMPQ_MPQ_ARCHIVE_SIZE 1 /* MPQ archive size */ +#define LIBMPQ_MPQ_HASHTABLE_SIZE 2 /* MPQ archive hashtable size */ +#define LIBMPQ_MPQ_BLOCKTABLE_SIZE 3 /* MPQ archive blocktable size */ +#define LIBMPQ_MPQ_BLOCKSIZE 4 /* MPQ archive blocksize */ +#define LIBMPQ_MPQ_NUMFILES 5 /* Number of files in the MPQ archive */ +#define LIBMPQ_MPQ_COMPRESSED_SIZE 6 /* Compressed archive size */ +#define LIBMPQ_MPQ_UNCOMPRESSED_SIZE 7 /* Uncompressed archive size */ -#define LIBMPQ_HUFF_DECOMPRESS 0 /* Defines that we want to decompress using huffman trees. */ +#define LIBMPQ_HUFF_DECOMPRESS 0 /* Defines that we want to decompress using huffman trees. */ -#define LIBMPQ_CONF_EFILE_OPEN -1 /* error if a specific listfile was forced and could not be opened. */ -#define LIBMPQ_CONF_EFILE_CORRUPT -2 /* listfile seems to be corrupt */ -#define LIBMPQ_CONF_EFILE_LIST_CORRUPT -3 /* listfile seems correct, but filelist is broken */ -#define LIBMPQ_CONF_EFILE_NOT_FOUND -4 /* error if no matching listfile found */ -#define LIBMPQ_CONF_EFILE_VERSION -5 /* libmpq version does not match required listfile version */ +#define LIBMPQ_CONF_EFILE_OPEN -1 /* error if a specific listfile was forced and could not be opened. */ +#define LIBMPQ_CONF_EFILE_CORRUPT -2 /* listfile seems to be corrupt */ +#define LIBMPQ_CONF_EFILE_LIST_CORRUPT -3 /* listfile seems correct, but filelist is broken */ +#define LIBMPQ_CONF_EFILE_NOT_FOUND -4 /* error if no matching listfile found */ +#define LIBMPQ_CONF_EFILE_VERSION -5 /* libmpq version does not match required listfile version */ #ifndef FALSE #define FALSE 0 @@ -102,95 +102,95 @@ #endif */ -typedef unsigned int mpq_buffer[LIBMPQ_TOOLS_BUFSIZE]; -typedef int (*DECOMPRESS)(char *, int *, char *, int); +typedef unsigned int mpq_buffer[LIBMPQ_TOOLS_BUFSIZE]; +typedef int (*DECOMPRESS)(char *, int *, char *, int); typedef struct { - unsigned long mask; /* Decompression bit */ - DECOMPRESS decompress; /* Decompression function */ + unsigned long mask; /* Decompression bit */ + DECOMPRESS decompress; /* Decompression function */ } decompress_table; /* MPQ file header */ typedef struct { - unsigned int id; /* The 0x1A51504D ('MPQ\x1A') signature */ - unsigned int offset; /* Offset of the first file (Relative to MPQ start) */ - unsigned int archivesize; /* Size of MPQ archive */ - unsigned short offsetsc; /* 0000 for SC and BW */ - unsigned short blocksize; /* Size of file block is (0x200 << blockSize) */ - unsigned int hashtablepos; /* File position of hashTable */ - unsigned int blocktablepos; /* File position of blockTable. Each entry has 16 bytes */ - unsigned int hashtablesize; /* Number of entries in hash table */ - unsigned int blocktablesize; /* Number of entries in the block table */ + unsigned int id; /* The 0x1A51504D ('MPQ\x1A') signature */ + unsigned int offset; /* Offset of the first file (Relative to MPQ start) */ + unsigned int archivesize; /* Size of MPQ archive */ + unsigned short offsetsc; /* 0000 for SC and BW */ + unsigned short blocksize; /* Size of file block is (0x200 << blockSize) */ + unsigned int hashtablepos; /* File position of hashTable */ + unsigned int blocktablepos; /* File position of blockTable. Each entry has 16 bytes */ + unsigned int hashtablesize; /* Number of entries in hash table */ + unsigned int blocktablesize; /* Number of entries in the block table */ } mpq_header; //} __attribute__ ((packed)) mpq_header; /* Hash entry. All files in the archive are searched by their hashes. */ typedef struct { - unsigned int name1; /* The first two unsigned ints */ - unsigned int name2; /* are the encrypted file name */ - unsigned int locale; /* Locale information. */ - unsigned int blockindex; /* Index to file description block */ + unsigned int name1; /* The first two unsigned ints */ + unsigned int name2; /* are the encrypted file name */ + unsigned int locale; /* Locale information. */ + unsigned int blockindex; /* Index to file description block */ } mpq_hash; /* File description block contains informations about the file */ typedef struct { - unsigned int filepos; /* Block file starting position in the archive */ - unsigned int csize; /* Compressed file size */ - unsigned int fsize; /* Uncompressed file size */ - unsigned int flags; /* Flags */ + unsigned int filepos; /* Block file starting position in the archive */ + unsigned int csize; /* Compressed file size */ + unsigned int fsize; /* Uncompressed file size */ + unsigned int flags; /* Flags */ } mpq_block; /* File handle structure used since Diablo 1.00 (0x38 bytes) */ typedef struct { - unsigned char filename[PATH_MAX]; /* filename of the actual file in the archive */ - int fd; /* File handle */ - unsigned int seed; /* Seed used for file decrypt */ - unsigned int filepos; /* Current file position */ - unsigned int offset; - unsigned int nblocks; /* Number of blocks in the file (incl. the last noncomplete one) */ - unsigned int *blockpos; /* Position of each file block (only for compressed files) */ - int blockposloaded; /* TRUE if block positions loaded */ - unsigned int offset2; /* (Number of bytes somewhere ?) */ - mpq_hash *mpq_h; /* Hash table entry */ - mpq_block *mpq_b; /* File block pointer */ - - /* Non-Storm.dll members */ - - unsigned int accessed; /* Was something from the file already read? */ + unsigned char filename[PATH_MAX]; /* filename of the actual file in the archive */ + int fd; /* File handle */ + unsigned int seed; /* Seed used for file decrypt */ + unsigned int filepos; /* Current file position */ + unsigned int offset; + unsigned int nblocks; /* Number of blocks in the file (incl. the last noncomplete one) */ + unsigned int *blockpos; /* Position of each file block (only for compressed files) */ + int blockposloaded; /* TRUE if block positions loaded */ + unsigned int offset2; /* (Number of bytes somewhere ?) */ + mpq_hash *mpq_h; /* Hash table entry */ + mpq_block *mpq_b; /* File block pointer */ + + /* Non-Storm.dll members */ + + unsigned int accessed; /* Was something from the file already read? */ } mpq_file; /* List handle structure */ typedef struct { - unsigned char mpq_version[10]; /* libmpq version required by the listfile */ - unsigned char mpq_name[PATH_MAX]; /* mpq archive name without full path */ - unsigned char mpq_type[20]; /* mpq archive type */ - unsigned char mpq_game[40]; /* blizzard title the file matches */ - unsigned char mpq_game_version[10]; /* game version */ - unsigned char **mpq_files; /* filelist */ + unsigned char mpq_version[10]; /* libmpq version required by the listfile */ + unsigned char mpq_name[PATH_MAX]; /* mpq archive name without full path */ + unsigned char mpq_type[20]; /* mpq archive type */ + unsigned char mpq_game[40]; /* blizzard title the file matches */ + unsigned char mpq_game_version[10]; /* game version */ + unsigned char **mpq_files; /* filelist */ } mpq_list; /* Archive handle structure used since Diablo 1.00 */ typedef struct { - unsigned char filename[PATH_MAX]; /* Opened archive file name */ - int fd; /* File handle */ - unsigned int blockpos; /* Position of loaded block in the file */ - unsigned int blocksize; /* Size of file block */ - unsigned char *blockbuf; /* Buffer (cache) for file block */ - unsigned int bufpos; /* Position in block buffer */ - unsigned int mpqpos; /* MPQ archive position in the file */ - unsigned int filepos; /* Current file pointer */ - unsigned int openfiles; /* Number of open files + 1 */ - mpq_buffer buf; /* MPQ buffer */ - mpq_header *header; /* MPQ file header */ - mpq_hash *hashtable; /* Hash table */ - mpq_block *blocktable; /* Block table */ - - /* Non-Storm.dll members */ - - mpq_list *mpq_l; /* Handle to file list from database */ - - unsigned int flags; /* See LIBMPQ_TOOLS_FLAG_XXXXX */ - unsigned int maxblockindex; /* The highest block table entry */ + unsigned char filename[PATH_MAX]; /* Opened archive file name */ + int fd; /* File handle */ + unsigned int blockpos; /* Position of loaded block in the file */ + unsigned int blocksize; /* Size of file block */ + unsigned char *blockbuf; /* Buffer (cache) for file block */ + unsigned int bufpos; /* Position in block buffer */ + unsigned int mpqpos; /* MPQ archive position in the file */ + unsigned int filepos; /* Current file pointer */ + unsigned int openfiles; /* Number of open files + 1 */ + mpq_buffer buf; /* MPQ buffer */ + mpq_header *header; /* MPQ file header */ + mpq_hash *hashtable; /* Hash table */ + mpq_block *blocktable; /* Block table */ + + /* Non-Storm.dll members */ + + mpq_list *mpq_l; /* Handle to file list from database */ + + unsigned int flags; /* See LIBMPQ_TOOLS_FLAG_XXXXX */ + unsigned int maxblockindex; /* The highest block table entry */ } mpq_archive; extern char *libmpq_version(); @@ -213,13 +213,13 @@ extern int libmpq_wave_decompress_mono(char *out_buf, int *out_length, char *in_ extern int libmpq_multi_decompress(char *out_buf, int *pout_length, char *in_buf, int in_length); static decompress_table dcmp_table[] = { - {0x08, libmpq_pkzip_decompress}, /* Decompression with Pkware Data Compression Library */ - {0x02, libmpq_zlib_decompress}, /* Decompression with the "zlib" library */ - {0x01, libmpq_huff_decompress}, /* Huffmann decompression */ - {0x80, libmpq_wave_decompress_stereo}, /* WAVE decompression for stereo waves */ - {0x40, libmpq_wave_decompress_mono} /* WAVE decompression for mono waves */ + {0x08, libmpq_pkzip_decompress}, /* Decompression with Pkware Data Compression Library */ + {0x02, libmpq_zlib_decompress}, /* Decompression with the "zlib" library */ + {0x01, libmpq_huff_decompress}, /* Huffmann decompression */ + {0x80, libmpq_wave_decompress_stereo}, /* WAVE decompression for stereo waves */ + {0x40, libmpq_wave_decompress_mono} /* WAVE decompression for mono waves */ }; int libmpq_file_extract(mpq_archive *mpq_a, const int number, const char *filename); int libmpq_file_getdata(mpq_archive *mpq_a, mpq_hash mpq_h, const int number, unsigned char *dest); -#endif /* _MPQ_H */ +#endif /* _MPQ_H */ diff --git a/contrib/extractor/libmpq/parser.cpp b/contrib/extractor/libmpq/parser.cpp index 435395b8767..5bd620aa74c 100644 --- a/contrib/extractor/libmpq/parser.cpp +++ b/contrib/extractor/libmpq/parser.cpp @@ -34,21 +34,21 @@ * deleted but \" would not. */ char *libmpq_conf_delete_char(char *buf, char *chars) { - static char *temp; - char ch; + static char *temp; + char ch; - temp = buf; + temp = buf; - /* strip out special chars like " */ - while (temp = strpbrk(temp, chars)) { - ch = temp[0]; - memmove(&temp[0], &temp[1], strlen(temp)); - if (ch == '\\') { - temp++; - } - } + /* strip out special chars like " */ + while (temp = strpbrk(temp, chars)) { + ch = temp[0]; + memmove(&temp[0], &temp[1], strlen(temp)); + if (ch == '\\') { + temp++; + } + } - return buf; + return buf; } /* @@ -56,65 +56,65 @@ char *libmpq_conf_delete_char(char *buf, char *chars) { * return 1 on success and the byte array or 0 and null. */ int libmpq_conf_parse_line(char *line, char *search_value, char *return_value, int size) { - int level = 0; - int found = 0; - int i = 0; - int pos = 0; - - /* search value */ - while (*(++line)) { - - /* check for spaces */ - if (!isspace(*line) && level == 1) { - - /* we found our value so break */ - found = 1; - break; - } - - /* check for '=' so the value follows as next parameter */ - if (*line == '=' && level == 0) { - level = 1; - } - } - - /* now search for comment in this line */ - for (i = 0; i < int(strlen(line)); i++) { - if (line[i] == '#') { - pos = i - 1; - break; - } - } - - /* now set end of byte array behind value, but only if comment was found */ - if (pos != 0) { - for (i = pos; i >= 0; i--) { - if (line[i] != ' ' && line[i] != '\t') { - line[i + 1] = '\0'; - break; - } - } - } - - /* now check if line has trailing spaces */ - for (i = strlen(line); i >= 0; i--) { - if (line[i] != ' ' && line[i] != '\t') { - line[i + 1] = '\0'; - break; - } - } - - /* now check if value is quoted with "" and if there is a char behind. */ - for (i = strlen(line); i >= 0; i--) { - if (line[i] == '"') { - line[i + 1] = '\0'; - break; - } - } - - /* return the values */ - strncpy(return_value, line, size); - return found; + int level = 0; + int found = 0; + int i = 0; + int pos = 0; + + /* search value */ + while (*(++line)) { + + /* check for spaces */ + if (!isspace(*line) && level == 1) { + + /* we found our value so break */ + found = 1; + break; + } + + /* check for '=' so the value follows as next parameter */ + if (*line == '=' && level == 0) { + level = 1; + } + } + + /* now search for comment in this line */ + for (i = 0; i < int(strlen(line)); i++) { + if (line[i] == '#') { + pos = i - 1; + break; + } + } + + /* now set end of byte array behind value, but only if comment was found */ + if (pos != 0) { + for (i = pos; i >= 0; i--) { + if (line[i] != ' ' && line[i] != '\t') { + line[i + 1] = '\0'; + break; + } + } + } + + /* now check if line has trailing spaces */ + for (i = strlen(line); i >= 0; i--) { + if (line[i] != ' ' && line[i] != '\t') { + line[i + 1] = '\0'; + break; + } + } + + /* now check if value is quoted with "" and if there is a char behind. */ + for (i = strlen(line); i >= 0; i--) { + if (line[i] == '"') { + line[i + 1] = '\0'; + break; + } + } + + /* return the values */ + strncpy(return_value, line, size); + return found; } /* @@ -122,70 +122,70 @@ int libmpq_conf_parse_line(char *line, char *search_value, char *return_value, i * listdb or config file. On success it returns 1, otherwise 0. */ int libmpq_conf_get_value(FILE *fp, char *search_value, void *return_value, int type, int size) { - char buf[LIBMPQ_CONF_BUFSIZE]; - int found = 0; - int result = LIBMPQ_TOOLS_SUCCESS; + char buf[LIBMPQ_CONF_BUFSIZE]; + int found = 0; + int result = LIBMPQ_TOOLS_SUCCESS; - while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) { - char *line; + while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) { + char *line; - buf[strlen(buf) - 1] = '\0'; + buf[strlen(buf) - 1] = '\0'; - /* skip whitespace */ - for (line = buf; isspace(*line); line++) { - continue; - } + /* skip whitespace */ + for (line = buf; isspace(*line); line++) { + continue; + } - /* skip empty line */ - if (line[0] == '\0') { - continue; - } + /* skip empty line */ + if (line[0] == '\0') { + continue; + } - /* skip comments */ - if (line[0] == '#') { - continue; - } + /* skip comments */ + if (line[0] == '#') { + continue; + } - /* process the line */ - //if (!strncasecmp(line, search_value, strlen(search_value))) { + /* process the line */ + //if (!strncasecmp(line, search_value, strlen(search_value))) { if (!strcmp(line, search_value)) { - found = libmpq_conf_parse_line(line, search_value, line, LIBMPQ_CONF_BUFSIZE); - if (found == 1) { - libmpq_conf_delete_char(line, "\"\\"); - - switch (type) { - case LIBMPQ_CONF_TYPE_INT: - - /* if it is no valid number it is safe to return 0 */ - *(int *)return_value = atoi(line); - break; - default: - strncpy((char *)return_value, line, size); - break; - } - - /* value found, so rewind stream */ - break; - } - } - } - - /* if value was not found */ - if (found == 0) { - switch (type) { - case LIBMPQ_CONF_TYPE_INT: - *(int *)return_value = 0; - result = LIBMPQ_CONF_EVALUE_NOT_FOUND; - break; - default: - strncpy((char *)return_value, "", size); - result = LIBMPQ_CONF_EVALUE_NOT_FOUND; - break; - } - } - fseek(fp, 0L, SEEK_SET); - - return result; + found = libmpq_conf_parse_line(line, search_value, line, LIBMPQ_CONF_BUFSIZE); + if (found == 1) { + libmpq_conf_delete_char(line, "\"\\"); + + switch (type) { + case LIBMPQ_CONF_TYPE_INT: + + /* if it is no valid number it is safe to return 0 */ + *(int *)return_value = atoi(line); + break; + default: + strncpy((char *)return_value, line, size); + break; + } + + /* value found, so rewind stream */ + break; + } + } + } + + /* if value was not found */ + if (found == 0) { + switch (type) { + case LIBMPQ_CONF_TYPE_INT: + *(int *)return_value = 0; + result = LIBMPQ_CONF_EVALUE_NOT_FOUND; + break; + default: + strncpy((char *)return_value, "", size); + result = LIBMPQ_CONF_EVALUE_NOT_FOUND; + break; + } + } + fseek(fp, 0L, SEEK_SET); + + return result; } /* @@ -194,101 +194,101 @@ int libmpq_conf_get_value(FILE *fp, char *search_value, void *return_value, int * entries in the byte array. On success it returns 1, otherwise 0. */ int libmpq_conf_get_array(FILE *fp, char *search_value, char ***filelist, int *entries) { - char buf[LIBMPQ_CONF_BUFSIZE]; - char temp[LIBMPQ_CONF_BUFSIZE]; - int level = 0; - int array_start = 0; - int array_end = 0; - int fl_count; - int fl_size; - int found = 0; - int i = 0; - - *entries = 0; - - /* allocate memory for the file list */ - (*filelist) = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *)); - fl_count = 0; - fl_size = LIBMPQ_CONF_FL_INCREMENT; - - while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) { - char *line; - - buf[strlen(buf) - 1] = '\0'; - - /* skip whitespace */ - for (line = buf; isspace(*line); line++) { - continue; - } - - /* skip empty line */ - if (line[0] == '\0') { - continue; - } - - /* skip comments */ - if (line[0] == '#') { - continue; - } - - /* check for array end ) */ - if (*line == ')') { - array_end = 1; - break; - } - - /* process entries between () */ - if (array_start == 1 && array_end == 0) { - - /* add dummy option to use with libmpq_conf_parse_line() */ - strncpy(temp, "MPQ_BUFFER = ", LIBMPQ_CONF_BUFSIZE); - strncat(temp, line, LIBMPQ_CONF_BUFSIZE); - found = libmpq_conf_parse_line(temp, "MPQ_BUFFER", temp, LIBMPQ_CONF_BUFSIZE); - - if (found == 1) { - libmpq_conf_delete_char(temp, "\"\\"); - - /* set the next filelist entry to a copy of the file */ - (*filelist)[fl_count++] = _strdup(temp); - - /* increase the array size */ - if (fl_count == fl_size) { - (*filelist) = (char **)realloc((*filelist), (fl_size + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *)); - fl_size += LIBMPQ_CONF_FL_INCREMENT; - } - - /* increase number of entries */ - (*entries)++; - } - } - - /* process the line and search array start */ - //if (!strncasecmp(line, search_value, strlen(search_value))) { + char buf[LIBMPQ_CONF_BUFSIZE]; + char temp[LIBMPQ_CONF_BUFSIZE]; + int level = 0; + int array_start = 0; + int array_end = 0; + int fl_count; + int fl_size; + int found = 0; + int i = 0; + + *entries = 0; + + /* allocate memory for the file list */ + (*filelist) = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *)); + fl_count = 0; + fl_size = LIBMPQ_CONF_FL_INCREMENT; + + while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) { + char *line; + + buf[strlen(buf) - 1] = '\0'; + + /* skip whitespace */ + for (line = buf; isspace(*line); line++) { + continue; + } + + /* skip empty line */ + if (line[0] == '\0') { + continue; + } + + /* skip comments */ + if (line[0] == '#') { + continue; + } + + /* check for array end ) */ + if (*line == ')') { + array_end = 1; + break; + } + + /* process entries between () */ + if (array_start == 1 && array_end == 0) { + + /* add dummy option to use with libmpq_conf_parse_line() */ + strncpy(temp, "MPQ_BUFFER = ", LIBMPQ_CONF_BUFSIZE); + strncat(temp, line, LIBMPQ_CONF_BUFSIZE); + found = libmpq_conf_parse_line(temp, "MPQ_BUFFER", temp, LIBMPQ_CONF_BUFSIZE); + + if (found == 1) { + libmpq_conf_delete_char(temp, "\"\\"); + + /* set the next filelist entry to a copy of the file */ + (*filelist)[fl_count++] = _strdup(temp); + + /* increase the array size */ + if (fl_count == fl_size) { + (*filelist) = (char **)realloc((*filelist), (fl_size + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *)); + fl_size += LIBMPQ_CONF_FL_INCREMENT; + } + + /* increase number of entries */ + (*entries)++; + } + } + + /* process the line and search array start */ + //if (!strncasecmp(line, search_value, strlen(search_value))) { if (!strcmp(line, search_value)) { - /* search value */ - while (*(++line)) { + /* search value */ + while (*(++line)) { - /* check for array start ( */ - if (*line == '(' && level == 1) { + /* check for array start ( */ + if (*line == '(' && level == 1) { - /* we found our value so break */ - array_start = 1; - break; - } + /* we found our value so break */ + array_start = 1; + break; + } - /* check for '=' so the value follows as next parameter */ - if (*line == '=' && level == 0) { - level = 1; - } - } - } - } + /* check for '=' so the value follows as next parameter */ + if (*line == '=' && level == 0) { + level = 1; + } + } + } + } - /* we got all files, so rewind stream */ - fseek(fp, 0L, SEEK_SET); + /* we got all files, so rewind stream */ + fseek(fp, 0L, SEEK_SET); - (*filelist)[fl_count] = NULL; + (*filelist)[fl_count] = NULL; - return found; + return found; } diff --git a/contrib/extractor/libmpq/wave.cpp b/contrib/extractor/libmpq/wave.cpp index 8edc1f7fa41..d5c59d8e085 100644 --- a/contrib/extractor/libmpq/wave.cpp +++ b/contrib/extractor/libmpq/wave.cpp @@ -29,25 +29,25 @@ /* Tables necessary dor decompression */ static unsigned long wave_table_1503f120[] = { - 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006, - 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, - 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, - 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008 + 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006, + 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, + 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, + 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008 }; static unsigned long wave_table_1503f1a0[] = { - 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, - 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F, - 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042, - 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F, - 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133, - 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292, - 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583, - 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0, - 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954, - 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B, - 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462, - 0x00007FFF + 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, + 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F, + 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042, + 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F, + 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133, + 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292, + 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583, + 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0, + 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954, + 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B, + 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462, + 0x00007FFF }; /* @@ -56,130 +56,130 @@ static unsigned long wave_table_1503f1a0[] = { * Offset: 1500F230 */ int libmpq_wave_decompress(unsigned char *out_buf, int out_length, unsigned char *in_buf, int in_length, int channels) { - byte_and_short out; - byte_and_short in; - unsigned char *in_end = in_buf + in_length; /* End on input buffer */ - unsigned long index; - long nr_array1[2]; - long nr_array2[2]; - int count = 0; + byte_and_short out; + byte_and_short in; + unsigned char *in_end = in_buf + in_length; /* End on input buffer */ + unsigned long index; + long nr_array1[2]; + long nr_array2[2]; + int count = 0; - out.pb = out_buf; - in.pb = in_buf; - nr_array1[0] = 0x2C; - nr_array1[1] = 0x2C; - in.pw++; + out.pb = out_buf; + in.pb = in_buf; + nr_array1[0] = 0x2C; + nr_array1[1] = 0x2C; + in.pw++; - /* 15007AD7 */ - for (count = 0; count < channels; count++) { - long temp; - temp = *(short *)in.pw++; - nr_array2[count] = temp; - if (out_length < 2) { - return out.pb - out_buf; - } - *out.pw++ = (unsigned short)temp; - out_length -= 2; - } - index = channels - 1; - while (in.pb < in_end) { - unsigned char one_byte = *in.pb++; - if (channels == 2) { - index = (index == 0) ? 1 : 0; - } + /* 15007AD7 */ + for (count = 0; count < channels; count++) { + long temp; + temp = *(short *)in.pw++; + nr_array2[count] = temp; + if (out_length < 2) { + return out.pb - out_buf; + } + *out.pw++ = (unsigned short)temp; + out_length -= 2; + } + index = channels - 1; + while (in.pb < in_end) { + unsigned char one_byte = *in.pb++; + if (channels == 2) { + index = (index == 0) ? 1 : 0; + } - /* - * Get one byte from input buffer - * 15007B25 - */ - if (one_byte & 0x80) { - /* 15007B32 */ - switch(one_byte & 0x7F) { - case 0: /* 15007B8E */ - if (nr_array1[index] != 0) { - nr_array1[index]--; - } - if (out_length < 2) { - break; - } - *out.pw++ = (unsigned short)nr_array2[index]; - out_length -= 2; - continue; - case 1: /* 15007B72 */ - nr_array1[index] += 8; /* EBX also */ - if (nr_array1[index] > 0x58) { - nr_array1[index] = 0x58; - } - if (channels == 2) { - index = (index == 0) ? 1 : 0; - } - continue; - case 2: - continue; - default: - nr_array1[index] -= 8; - if (nr_array1[index] < 0) { - nr_array1[index] = 0; - } - if (channels != 2) { - continue; - } - index = (index == 0) ? 1 : 0; - continue; - } - } else { - unsigned long temp1 = wave_table_1503f1a0[nr_array1[index]]; /* EDI */ - unsigned long temp2 = temp1 >> in_buf[1]; /* ESI */ - long temp3 = nr_array2[index]; /* ECX */ - if (one_byte & 0x01) { /* EBX = one_byte */ - temp2 += (temp1 >> 0); - } - if (one_byte & 0x02) { - temp2 += (temp1 >> 1); - } - if (one_byte & 0x04) { - temp2 += (temp1 >> 2); - } - if (one_byte & 0x08) { - temp2 += (temp1 >> 3); - } - if (one_byte & 0x10) { - temp2 += (temp1 >> 4); - } - if (one_byte & 0x20) { - temp2 += (temp1 >> 5); - } - if(one_byte & 0x40) { - temp3 -= temp2; - if (temp3 <= (long)0xFFFF8000) { - temp3 = (long)0xFFFF8000; - } - } else { - temp3 += temp2; - if (temp3 >= 0x7FFF) { - temp3 = 0x7FFF; - } - } - nr_array2[index] = temp3; - if (out_length < 2) { - break; - } + /* + * Get one byte from input buffer + * 15007B25 + */ + if (one_byte & 0x80) { + /* 15007B32 */ + switch(one_byte & 0x7F) { + case 0: /* 15007B8E */ + if (nr_array1[index] != 0) { + nr_array1[index]--; + } + if (out_length < 2) { + break; + } + *out.pw++ = (unsigned short)nr_array2[index]; + out_length -= 2; + continue; + case 1: /* 15007B72 */ + nr_array1[index] += 8; /* EBX also */ + if (nr_array1[index] > 0x58) { + nr_array1[index] = 0x58; + } + if (channels == 2) { + index = (index == 0) ? 1 : 0; + } + continue; + case 2: + continue; + default: + nr_array1[index] -= 8; + if (nr_array1[index] < 0) { + nr_array1[index] = 0; + } + if (channels != 2) { + continue; + } + index = (index == 0) ? 1 : 0; + continue; + } + } else { + unsigned long temp1 = wave_table_1503f1a0[nr_array1[index]]; /* EDI */ + unsigned long temp2 = temp1 >> in_buf[1]; /* ESI */ + long temp3 = nr_array2[index]; /* ECX */ + if (one_byte & 0x01) { /* EBX = one_byte */ + temp2 += (temp1 >> 0); + } + if (one_byte & 0x02) { + temp2 += (temp1 >> 1); + } + if (one_byte & 0x04) { + temp2 += (temp1 >> 2); + } + if (one_byte & 0x08) { + temp2 += (temp1 >> 3); + } + if (one_byte & 0x10) { + temp2 += (temp1 >> 4); + } + if (one_byte & 0x20) { + temp2 += (temp1 >> 5); + } + if(one_byte & 0x40) { + temp3 -= temp2; + if (temp3 <= (long)0xFFFF8000) { + temp3 = (long)0xFFFF8000; + } + } else { + temp3 += temp2; + if (temp3 >= 0x7FFF) { + temp3 = 0x7FFF; + } + } + nr_array2[index] = temp3; + if (out_length < 2) { + break; + } - temp2 = nr_array1[index]; - one_byte &= 0x1F; - *out.pw++ = (unsigned short)temp3; - out_length -= 2; - temp2 += wave_table_1503f120[one_byte]; - nr_array1[index] = temp2; + temp2 = nr_array1[index]; + one_byte &= 0x1F; + *out.pw++ = (unsigned short)temp3; + out_length -= 2; + temp2 += wave_table_1503f120[one_byte]; + nr_array1[index] = temp2; - if (nr_array1[index] < 0) { - nr_array1[index] = 0; - } else { - if (nr_array1[index] > 0x58) { - nr_array1[index] = 0x58; - } - } - } - } - return (out.pb - out_buf); + if (nr_array1[index] < 0) { + nr_array1[index] = 0; + } else { + if (nr_array1[index] > 0x58) { + nr_array1[index] = 0x58; + } + } + } + } + return (out.pb - out_buf); } diff --git a/contrib/extractor/libmpq/wave.h b/contrib/extractor/libmpq/wave.h index 8920880a04f..996e8c6777f 100644 --- a/contrib/extractor/libmpq/wave.h +++ b/contrib/extractor/libmpq/wave.h @@ -22,16 +22,16 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ + */ #ifndef _WAVE_H #define _WAVE_H typedef union { - unsigned short *pw; - unsigned char *pb; + unsigned short *pw; + unsigned char *pb; } byte_and_short; int libmpq_wave_decompress(unsigned char *out_buf, int out_length, unsigned char *in_buf, int in_length, int channels); -#endif /* _WAVE_H */ +#endif /* _WAVE_H */ |