void CheckPPFCache(unsigned char *pB, unsigned char m, unsigned char s, unsigned char f) { PPF_CACHE *pcstart, *pcend, *pcpos; int addr = MSF2SECT(btoi(m), btoi(s), btoi(f)), pos, anz, start; if (ppfCache == NULL) return; pcstart = ppfCache; if (addr < pcstart->addr) return; pcend = ppfCache + iPPFNum; if (addr > pcend->addr) return; while (1) { if (addr == pcend->addr) { pcpos = pcend; break; } pcpos = pcstart + (pcend - pcstart) / 2; if (pcpos == pcstart) break; if (addr < pcpos->addr) { pcend = pcpos; continue; } if (addr > pcpos->addr) { pcstart = pcpos; continue; } break; } if (addr == pcpos->addr) { PPF_DATA *p = pcpos->pNext; while (p != NULL && p->addr == addr) { pos = p->pos - (CD_FRAMESIZE_RAW - DATA_SIZE); anz = p->anz; if (pos < 0) { start = -pos; pos = 0; anz -= start; } else start = 0; memcpy(pB + pos, (unsigned char *)(p + 1) + start, anz); p = p->pNext; } } }
// read track // time : int 0 - minute ; int 1 - second ; int 2 - frame // uses int format s32 CDR_readTrack(u8 *time) { // check cache for current sector u32 curr_sector = MSF2SECT((time[0]), (time[1]), (time[2])); s32 i; u8 minute = (time[0]); if( curr_sector >= cdlastsector && curr_sector < cdlastsector + BUFFER_SECTORS ) { cdlastbuffer = (u8*)((u32)cdbuffer + ((curr_sector - cdlastsector) * CD_FRAMESIZE_RAW)); return 0; } // Not found in cache... cdlastsector = curr_sector; cdlastbuffer = cdbuffer; if (!fmode) { fseek(cdHandle, curr_sector * CD_FRAMESIZE_RAW, SEEK_SET); fread(cdlastbuffer, (CD_FRAMESIZE_RAW*BUFFER_SECTORS), 1, cdHandle); } else if (fmode == 1) { //.Z int ret; for(i = 0; i < BUFFER_SECTORS; i++) { u32 pos, p; u32 size; u8 Zbuf[CD_FRAMESIZE_RAW+256]; p = curr_sector + i; pos = (u32)(Ztable[p * 6] | (Ztable[p * 6 + 1] << 8) | (Ztable[p * 6 + 2] << 16) | (Ztable[p * 6 + 3] << 24)); fseek(cdHandle, pos, SEEK_SET); p = (u16)(Ztable[p * 6 + 4] | (Ztable[p * 6 + 4 + 1] << 8)); fread(Zbuf, p, 1, cdHandle); size = CD_FRAMESIZE_RAW; ret = uncompress(cdlastbuffer + (i * CD_FRAMESIZE_RAW), &size, Zbuf, p); if( ret != Z_OK ) { printf("uncompress error %d !\n", ret); gp2x_deinit(); } } } else if (fmode == 2) { // .bz SysPrintf("BZ FORMAT IS NOT SUPPORTED."); } else { // .ZNX for(i = 0; i < BUFFER_SECTORS; i++) { int ret; u32 pos, p; u32 size; u8 Zbuf[CD_FRAMESIZE_RAW+256]; p = curr_sector + i; pos = (u32)(Ztable[p * 10] | (Ztable[p * 10 + 1] << 8) | (Ztable[p * 10 + 2] << 16) | (Ztable[p * 10 + 3] << 24)); fseek(cdHandle, pos, SEEK_SET); p = (u16)(Ztable[p * 10 + 4] | (Ztable[p * 10 + 4 + 1] << 8)); fread(Zbuf, p, 1, cdHandle); size = CD_FRAMESIZE_RAW; ret = uncompress(cdlastbuffer + (i * CD_FRAMESIZE_RAW), &size, Zbuf, p); if( ret != Z_OK ) { printf("uncompress error %d !\n", ret); gp2x_deinit(); } } } return 0; }
// read track // time: byte 0 - minute; byte 1 - second; byte 2 - frame // uses bcd format static long CDRreadTrack(unsigned char *time) { unsigned int start_byte, size; unsigned long cdbuffer_size; int ret, sector, block; if (cd_file == NULL) return -1; sector = MSF2SECT(btoi(time[0]), btoi(time[1]), btoi(time[2])); // avoid division if possible switch (cd_sectors_per_blk) { case 1: block = sector; current_sect_in_blk = 0; break; case 10: block = sector / 10; current_sect_in_blk = sector % 10; break; case 16: block = sector >> 4; current_sect_in_blk = sector & 15; break; default: err("unhandled cd_sectors_per_blk: %d\n", cd_sectors_per_blk); return -1; } if (block == current_block) { // it's already there, nothing to do //printf("hit sect %d\n", sector); return 0; } if (sector >= cd_index_len * cd_sectors_per_blk) { err("sector %d is past track end\n", sector); return -1; } start_byte = cd_index_table[block]; if (fseek(cd_file, start_byte, SEEK_SET) != 0) { err("seek error for block %d at %x: ", block, start_byte); perror(NULL); return -1; } size = cd_index_table[block + 1] - start_byte; if (size > sizeof(cdbuffer->compressed)) { err("block %d is too large: %u\n", block, size); return -1; } if (fread(cdbuffer->compressed, 1, size, cd_file) != size) { err("read error for block %d at %x: ", block, start_byte); perror(NULL); return -1; } cdbuffer_size = sizeof(cdbuffer->raw[0]) * cd_sectors_per_blk; switch (cd_compression) { case CDRC_ZLIB: ret = uncompress(cdbuffer->raw[0], &cdbuffer_size, cdbuffer->compressed, size); break; case CDRC_ZLIB2: ret = uncompress2(cdbuffer->raw[0], &cdbuffer_size, cdbuffer->compressed, size); break; case CDRC_BZ: ret = BZ2_bzBuffToBuffDecompress((char *)cdbuffer->raw, (unsigned int *)&cdbuffer_size, (char *)cdbuffer->compressed, size, 0, 0); break; default: err("bad cd_compression: %d\n", cd_compression); return -1; } if (ret != 0) { err("uncompress failed with %d for block %d, sector %d\n", ret, block, sector); return -1; } if (cdbuffer_size != sizeof(cdbuffer->raw[0]) * cd_sectors_per_blk) err("cdbuffer_size: %lu != %d, sector %d\n", cdbuffer_size, sizeof(cdbuffer->raw[0]) * cd_sectors_per_blk, sector); // done at last! current_block = block; return 0; }