// ******************************************************************************************** bool BitStream::OpenRA(const char *file_name) { if (file) fclose(file); if ((file = my_fopen(file_name, "rb")) != NULL) mode = FILE_MODE_READ_RA; IO_BUFFER_SIZE = BitStream::DEFAULT_IO_BUFFER_SIZE_RA; io_buffer = new uchar[IO_BUFFER_SIZE]; io_buffer_size = IO_BUFFER_SIZE; word_buffer_size = 8; io_buffer_pos = IO_BUFFER_SIZE; file_pos = 0; if (mode == FILE_MODE_READ_RA) { my_fseek(file, 0, SEEK_END); file_size = my_ftell(file); my_fseek(file, 0, SEEK_SET); } return mode == FILE_MODE_READ_RA; }
static void file_check_midi(file_recovery_t *file_recovery) { const uint64_t fs_org=file_recovery->file_size; struct midi_header hdr; unsigned int i; unsigned int tracks; uint64_t fs=4+4+6; file_recovery->file_size=0; if(my_fseek(file_recovery->handle, 0, SEEK_SET) < 0 || fread(&hdr, sizeof(hdr), 1, file_recovery->handle) != 1) return ; tracks=be16(hdr.tracks); for(i=0; i<tracks; i++) { struct midi_header track; #ifdef DEBUG_MIDI log_info("file_check_midi 0x%08llx\n", (unsigned long long)fs); #endif if(my_fseek(file_recovery->handle, fs, SEEK_SET) < 0 || fread(&track, 8, 1, file_recovery->handle) != 1 || memcmp(&track.magic[0], "MTrk", 4)!=0) return ; fs+=8+be32(track.len); } if(fs_org < fs) return ; file_recovery->file_size=fs; }
static uint32_t *OLE_load_FAT(FILE *IN, const struct OLE_HDR *header) { uint32_t *fat; uint32_t *dif; dif=(uint32_t*)MALLOC(109*4+(le32(header->num_extra_FAT_blocks)<<le16(header->uSectorShift))); memcpy(dif,(header+1),109*4); if(le32(header->num_extra_FAT_blocks)>0) { /* Load DIF*/ unsigned long int i; unsigned long int block; unsigned char *data=(unsigned char*)&dif[109]; for(i=0, block=le32(header->FAT_next_block); i<le32(header->num_extra_FAT_blocks) && block!=0xFFFFFFFF && block!=0xFFFFFFFE; i++, block=le32(dif[109+i*(((1<<le16(header->uSectorShift))/4)-1)])) { if(my_fseek(IN, (1+block)<<le16(header->uSectorShift), SEEK_SET) < 0) { free(dif); return NULL; } if(fread(data, 1<<le16(header->uSectorShift), 1, IN)!=1) { free(dif); return NULL; } data+=(1<<le16(header->uSectorShift))-4; } } fat=(uint32_t*)MALLOC(le32(header->num_FAT_blocks)<<le16(header->uSectorShift)); { /* Load FAT */ unsigned long int j; unsigned char *data; for(j=0, data=(unsigned char*)fat; j<le32(header->num_FAT_blocks); j++, data+=(1<<le16(header->uSectorShift))) { if(my_fseek(IN, (1+le32(dif[j]))<<le16(header->uSectorShift), SEEK_SET)<0) { free(dif); free(fat); return NULL; } if(fread(data, (1<<le16(header->uSectorShift)), 1, IN)!=1) { free(dif); free(fat); return NULL; } } } free(dif); return fat; }
static uint32_t *OLE_load_MiniFAT(FILE *IN, const struct OLE_HDR *header, const uint32_t *fat, const unsigned int fat_entries) { unsigned char*minifat_pos; uint32_t *minifat; unsigned int block; unsigned int i; if(le32(header->csectMiniFat)==0) return NULL; minifat=(uint32_t*)MALLOC(le32(header->csectMiniFat) << le16(header->uSectorShift)); minifat_pos=(unsigned char*)minifat; block=le32(header->MiniFat_block); for(i=0; i < le32(header->csectMiniFat) && block < fat_entries; i++) { if(my_fseek(IN, ((uint64_t)1+block) << le16(header->uSectorShift), SEEK_SET) < 0) { free(minifat); return NULL; } if(fread(minifat_pos, 1 << le16(header->uSectorShift), 1, IN) != 1) { free(minifat); return NULL; } minifat_pos+=1 << le16(header->uSectorShift); block=le32(fat[block]); } return minifat; }
static void file_check_axx(file_recovery_t *fr) { uint64_t offset=0x10; while(1) { struct SHeader header; unsigned int len; if(my_fseek(fr->handle, offset, SEEK_SET) < 0) return ; if (fread(&header, sizeof(header), 1, fr->handle)!=1) return ; len=le32(header.aoLength); #ifdef DEBUG_AAX log_info("axx 0x%llx 0x%x 0x%x/%d\n", (long long int)offset, len, header.oType, header.oType); #endif if(len<5) return ; offset+=len; if(header.oType==63) // eData { uint64_t fsize; if(len!=13) return ; if (fread(&fsize, sizeof(fsize), 1, fr->handle)!=1) return ; fsize=le64(fsize); offset+=fsize; fr->file_size=(fr->file_size < offset ? 0 : offset); return ; } } }
static void *OLE_read_stream(FILE *IN, const uint32_t *fat, const unsigned int fat_entries, const unsigned int uSectorShift, const unsigned int block_start, const unsigned int len) { unsigned char *dataPt; unsigned int block; unsigned int size_read; dataPt=(unsigned char *)MALLOC((len+(1<<uSectorShift)-1) / (1<<uSectorShift) * (1<<uSectorShift)); for(block=block_start, size_read=0; size_read < len; block=le32(fat[block]), size_read+=(1<<uSectorShift)) { if(!(block < fat_entries)) { free(dataPt); return NULL; } if(my_fseek(IN, (1+block)<<uSectorShift, SEEK_SET)<0) { free(dataPt); return NULL; } if(fread(&dataPt[size_read], (1<<uSectorShift), 1, IN)!=1) { free(dataPt); return NULL; } } return dataPt; }
static void file_check_gif(file_recovery_t *file_recovery) { const unsigned char gif_footer[2]= {0x00, 0x3b}; unsigned char buffer[2]; if(my_fseek(file_recovery->handle, file_recovery->calculated_file_size-2, SEEK_SET)<0 || fread(buffer, 2, 1, file_recovery->handle)!=1 || memcmp(buffer, gif_footer, sizeof(gif_footer))!=0) { file_recovery->file_size=0; return; } file_recovery->file_size=file_recovery->calculated_file_size; }
static void file_check_tib2(file_recovery_t *file_recovery) { unsigned char*buffer=(unsigned char*)MALLOC(512); int64_t file_size=file_recovery->calculated_file_size-512; file_recovery->file_size = file_recovery->calculated_file_size; if(my_fseek(file_recovery->handle, file_size, SEEK_SET) < 0 || fread(buffer, 1, 512, file_recovery->handle) != 512) { free(buffer); file_recovery->file_size=0; return; } if(memcmp(&buffer[512 - sizeof(tib2_footer)], tib2_footer, sizeof(tib2_footer))==0) { free(buffer); return; } for(; file_size>0; file_size-=512) { unsigned int i; if(my_fseek(file_recovery->handle, file_size, SEEK_SET) < 0 || fread(buffer, 1, 512, file_recovery->handle) != 512) { free(buffer); file_recovery->file_size=0; return; } for(i=0; i<512 && buffer[i]==0; i++); if(i!=512) { file_recovery->file_size=file_size + 512; free(buffer); return ; } } free(buffer); }
static void file_check_png(file_recovery_t *fr) { if(fr->file_size<fr->calculated_file_size) { fr->file_size=0; return ; } fr->file_size=8; while(1) { char buffer[8]; const struct png_chunk *chunk=(const struct png_chunk *)&buffer; if(my_fseek(fr->handle, fr->file_size, SEEK_SET) < 0 || fread(&buffer, sizeof(buffer), 1, fr->handle) != 1) { fr->file_size=0; return ; } fr->file_size+=12 + be32(chunk->length); if(memcmp(&buffer[4], "IEND", 4)==0) return ; } }
// ******************************************************************************************** bool BitStream::SetPos(uint64 pos) { if (mode != FILE_MODE_READ && mode != FILE_MODE_READ_RA) return false; if (pos >= file_pos - io_buffer_pos && pos < file_pos - io_buffer_pos + io_buffer_size) { io_buffer_pos = (int32) (pos - (file_pos - io_buffer_pos)); } else { if (my_fseek(file, pos, SEEK_SET) == EOF) return false; io_buffer_pos = IO_BUFFER_SIZE; file_pos = pos; } word_buffer_pos = 0; word_buffer = 0; return true; }
static void check_riff_list(file_recovery_t *fr, const unsigned int depth, const uint64_t start, const uint64_t end) { uint64_t file_size; riff_list_header list_header; if(depth>5) return; for(file_size=start; file_size < end;) { if(my_fseek(fr->handle, file_size, SEEK_SET)<0) { fr->offset_error=file_size; return; } if (fread(&list_header, sizeof(list_header), 1, fr->handle)!=1) { fr->offset_error=file_size; return; } if(memcmp(&list_header.dwList, "LIST", 4) == 0) { #ifdef DEBUG_RIFF log_riff_list(file_size, depth, &list_header); #endif check_riff_list(fr, depth+1, file_size + sizeof(list_header), file_size + 8 - 1 + le32(list_header.dwSize)); } else { #ifdef DEBUG_RIFF /* It's a chunk */ log_riff_chunk(file_size, depth, &list_header); #endif } file_size += 8 + le32(list_header.dwSize); /* align to word boundary */ file_size += (file_size&1); } }
static void file_check_indd(file_recovery_t *file_recovery) { const uint64_t file_size_org=file_recovery->file_size; struct InDesignContigObjMarker hdr; uint64_t offset; if(file_recovery->file_size<file_recovery->calculated_file_size) { file_recovery->file_size=0; return ; } offset=file_recovery->calculated_file_size; do { #ifdef DEBUG_INDD log_info("file_check_indd offset=%llu (0x%llx)\n", (long long unsigned)offset, (long long unsigned)offset); #endif if(my_fseek(file_recovery->handle, offset, SEEK_SET) < 0) { file_recovery->file_size=0; return ; } if(fread(&hdr, sizeof(hdr), 1, file_recovery->handle) != 1 || memcmp(hdr.fGUID, kINDDContigObjHeaderGUID, sizeof(kINDDContigObjHeaderGUID))!=0) { file_recovery->file_size=(offset+4096-1)/4096*4096; if(file_recovery->file_size>file_size_org) file_recovery->file_size=0; return ; } /* header + data + trailer */ offset+=(uint64_t)le32(hdr.fStreamLength)+2*sizeof(struct InDesignContigObjMarker); } while(offset < file_size_org); file_recovery->file_size=(offset+4096-1)/4096*4096; if(file_recovery->file_size>file_size_org) file_recovery->file_size=0; return ; }
static void file_check_avi(file_recovery_t *fr) { fr->file_size = 0; fr->offset_error=0; fr->offset_ok=0; while(fr->file_size!=fr->calculated_file_size) { const uint64_t file_size=fr->file_size; riff_list_header list_header; if(my_fseek(fr->handle, fr->file_size, SEEK_SET)<0) { fr->file_size=0; return ; } if (fread(&list_header, sizeof(list_header), 1, fr->handle)!=1) { fr->file_size=0; return; } #ifdef DEBUG_RIFF log_riff_list(file_size, 0, &list_header); #endif if(memcmp(&list_header.dwList, "RIFF", 4) != 0) { fr->offset_error=fr->file_size; return; } check_riff_list(fr, 1, file_size + sizeof(list_header), file_size + 8 - 1 + le32(list_header.dwSize)); if(fr->offset_error > 0) { fr->file_size=0; return; } fr->file_size=file_size + 8 + le32(list_header.dwSize); } }
int main(int argc, char *argv[]) { const char *starter_name; const char *exe_name; FILE *exe_file; int err; ElfW(Ehdr) ehdr_exe; ElfW(Phdr) *phdrs_exe; off_t offset = 0; off_t exe_size; off_t starter_size; unsigned char *starter_mem; pgm_name = argv[0]; if (argc != 3) { fprintf( stderr, "Usage: %s <starter> <exe>\n", pgm_name ); exit(1); } starter_name = argv[1]; exe_name = argv[2]; /* Get executable's ehdr */ err = get_ehdr_phdrs_and_shdrs( exe_name, &ehdr_exe, &phdrs_exe, NULL, NULL, NULL ); if (err == -1) exit(1); /* Find where in the file starter should be placed */ { int i; for (i = 0; i < ehdr_exe.e_phnum; i++) { /* It should be in the PT_LOAD segment */ if (phdrs_exe[i].p_type != PT_LOAD) continue; if ( (ehdr_exe.e_entry >= phdrs_exe[i].p_vaddr) && (ehdr_exe.e_entry < phdrs_exe[i].p_vaddr + phdrs_exe[i].p_memsz) ) { offset = ehdr_exe.e_entry - phdrs_exe[i].p_vaddr + phdrs_exe[i].p_offset; break; } } } if (offset == 0) { fprintf( stderr, "%s: can't find PT_LOAD segment with e_entry=0x%lx.\n", pgm_name, (unsigned long)ehdr_exe.e_entry ); exit(1); } /* Get size of the exe file */ exe_size = my_file_size(exe_name, &err); if (err == -1) exit(1); /* read starter file */ starter_mem = my_fread_whole_file( starter_name, "starter", &starter_size ); /* Sanity */ if (exe_size < (starter_size + offset) ) { fprintf( stderr, "%s: mismatch: starter offset=%lu(0x%lx) + starter size=%lu > exe_size=%lu\n", pgm_name, offset, offset, starter_size, exe_size ); exit(1); } /* Open for read/write */ exe_file = my_fopen(exe_name, "r+"); if (exe_file == NULL) exit(1); /* Position file to the place where starter should begin */ err = my_fseek(exe_file, offset, exe_name); if (err == -1) exit(1); /* Write starter */ err = my_fwrite( starter_mem, starter_size, exe_file, exe_name, "starter" ); if (err == -1) exit(1); /* Close file */ err = my_fclose(exe_file, exe_name); if (err == -1) exit(1); /* all done, exit */ exit(0); }
USE MENU #ifdef USE_MENU void mjpegTouch(int id, uint32_t pointed_chunk) // ? ? ? ? ? ? ? ? ? ? Touch pen interrupt processing { uint32_t firstChunk, prevChunk, prevSamples, samples, totalSamples = 0, jFrameOffset; MY_FILE fp_stsc, fp_stsz, fp_stco, fp_frame, fp_frame_cp; uint8_t atombuf[12]; raw_video_typedef raw; memcpy((void*)&fp_stsc, (void*)&video_stsc.fp, sizeof(MY_FILE)); memcpy((void*)&fp_stsz, (void*)&video_stsz.fp, sizeof(MY_FILE)); memcpy((void*)&fp_stco, (void*)&video_stco.fp, sizeof(MY_FILE)); //DANI memcpy((void*)&fp_frame, (void*)&fp_global, sizeof(MY_FILE)); // debug.printf("\r\npointed_chunk:%d video_stco.numEntry:%d", pointed_chunk, video_stco.numEntry); prevChunk = getSampleSize(atombuf, 12, &fp_stsc); // firstChunk samplesPerChunk sampleDescriptionID ????firstChunk?prevChunk? prevSamples = getAtomSize(&atombuf[4]); // ????samplesPerChunk?prevSamples? firstChunk = getSampleSize(atombuf, 4, &fp_stsc); // ????firstChunk while(1){ if(prevChunk <= pointed_chunk && firstChunk >= pointed_chunk){ samples = (firstChunk - pointed_chunk) * prevSamples; totalSamples += (pointed_chunk - prevChunk) * prevSamples; break; } samples = (firstChunk - prevChunk) * prevSamples; totalSamples += samples; prevChunk = firstChunk; // ???firstChunk?prevChunk? prevSamples = getSampleSize(atombuf, 8, &fp_stsc); // samplesPerChunk sampleDescriptionID firstChunk = getSampleSize(atombuf, 4, &fp_stsc); // ??firstChunk } my_fseek(&fp_stco, (pointed_chunk - 1) * 4, SEEK_CUR); jFrameOffset = getSampleSize(atombuf, 4, &fp_stco); memcpy((void*)&fp_stco, (void*)&video_stco.fp, sizeof(MY_FILE)); my_fseek(&fp_stco, (pointed_chunk - 1) * 4, SEEK_CUR); // my_fseek(&fp_frame, jFrameOffset, SEEK_SET); memcpy((void*)&fp_frame_cp, (void*)&fp_frame, sizeof(MY_FILE)); //DANI my_fseek(&fp_frame, raw.frame_size, SEEK_CUR); *pv_src.firstChunk = firstChunk; *pv_src.prevChunk = prevChunk; *pv_src.prevSamples = prevSamples; *pv_src.samples = samples; *pv_src.totalSamples = totalSamples; *pv_src.videoStcoCount = pointed_chunk + 1; memcpy((void*)pv_src.fp_video_stsc, (void*)&fp_stsc, sizeof(MY_FILE)); memcpy((void*)pv_src.fp_video_stsz, (void*)&fp_stsz, sizeof(MY_FILE)); memcpy((void*)pv_src.fp_video_stco, (void*)&fp_stco, sizeof(MY_FILE)); memcpy((void*)pv_src.fp_frame, (void*)&fp_frame, sizeof(MY_FILE)); // Sound memcpy((void*)&fp_stsc, (void*)&sound_stsc.fp, sizeof(MY_FILE)); memcpy((void*)&fp_stsz, (void*)&sound_stsz.fp, sizeof(MY_FILE)); memcpy((void*)&fp_stco, (void*)&sound_stco.fp, sizeof(MY_FILE)); //DANI memcpy((void*)&fp_frame, (void*)&fp_global, sizeof(MY_FILE)); // debug.printf("\r\npointed_chunk:%d video_stco.numEntry:%d", pointed_chunk, video_stco.numEntry); prevChunk = getSampleSize(atombuf, 12, &fp_stsc); // firstChunk samplesPerChunk sampleDescriptionID ????firstChunk?prevChunk? prevSamples = getAtomSize(&atombuf[4]); // ????samplesPerChunk?prevSamples? firstChunk = getSampleSize(atombuf, 4, &fp_stsc); // ????firstChunk totalSamples = 0; while(1){ if(prevChunk <= pointed_chunk && firstChunk >= pointed_chunk){ samples = (firstChunk - pointed_chunk) * prevSamples; totalSamples += (pointed_chunk - prevChunk) * prevSamples; break; } samples = (firstChunk - prevChunk) * prevSamples; totalSamples += samples; prevChunk = firstChunk; // ???firstChunk?prevChunk? prevSamples = getSampleSize(atombuf, 8, &fp_stsc); // samplesPerChunk sampleDescriptionID firstChunk = getSampleSize(atombuf, 4, &fp_stsc); // ??firstChunk } my_fseek(&fp_stco, (pointed_chunk - 1) * 4, SEEK_CUR); *ps_src.firstChunk = firstChunk; *ps_src.prevChunk = prevChunk; *ps_src.prevSamples = prevSamples; *ps_src.samples = samples; *ps_src.soundStcoCount = pointed_chunk; memcpy((void*)ps_src.fp_sound_stsc, (void*)&fp_stsc, sizeof(MY_FILE)); memcpy((void*)ps_src.fp_sound_stsz, (void*)&fp_stsz, sizeof(MY_FILE)); memcpy((void*)ps_src.fp_sound_stco, (void*)&fp_stco, sizeof(MY_FILE)); if(mjpeg_touch.resynch){ return; } /* //DANI if(media.video.width != LCD_WIDTH || media.video.height != LCD_HEIGHT){ LCD_DrawSquare(0, 0, LCD_WIDTH, media.video.startPosY, BLACK); LCD_DrawSquare(0, media.video.startPosY, (LCD_WIDTH - media.video.width) / 2, media.video.height, BLACK); LCD_DrawSquare(media.video.startPosX + media.video.width, media.video.startPosY, (LCD_WIDTH - media.video.width) / 2, media.video.height, BLACK); LCD_DrawSquare(0, media.video.startPosY + media.video.height, LCD_WIDTH, LCD_HEIGHT - (media.video.startPosY + media.video.height), BLACK); } */ int v; for(v = 0;v < media.video.height;v++) { //(&frame_buffer[media.video.startPosX + v * LCD_WIDTH + media.video.startPosY * LCD_WIDTH], 2, media.video.width, &fp_frame_cp); // read_file (FIL *file, uint8_t *buf, uint32_t sizeofbuf) } int curX, prevX, duration = (int)((float)media.video.duration / (float)media.video.timeScale + 0.5f); int time = duration * (float)*pv_src.videoStcoCount / (float)video_stco.numEntry; char timeStr[20]; LCDPutIcon(4, 100, 12, 12, pause_icon_12x12, pause_icon_12x12_alpha); LCDPutIcon(UI_POS_X, UI_POS_Y, 120, 14, seekbar_120x14, seekbar_120x14_alpha); drawBuff->navigation_loop.x = 140; drawBuff->navigation_loop.y = UI_POS_Y; drawBuff->navigation_loop.width = 18; drawBuff->navigation_loop.height = 14; LCDStoreBgImgToBuff(drawBuff->navigation_loop.x, drawBuff->navigation_loop.y, \ drawBuff->navigation_loop.width, drawBuff->navigation_loop.height, drawBuff->navigation_loop.p); Update_Navigation_Loop_Icon(drawBuff, music_control.b.navigation_loop_mode); drawBuff->posision.width = 12; drawBuff->posision.height = 12; drawBuff->posision.x = UI_POS_X + 1; drawBuff->posision.y = UI_POS_Y + 1; prevX = UI_POS_X + 1; LCDStoreBgImgToBuff(prevX, drawBuff->posision.y, \ drawBuff->posision.width, drawBuff->posision.height, drawBuff->posision.p); DRAW_SEEK_CIRCLE((float)time / (float)duration , seek_active_circle_12x12); pcf_typedef pcf; pcf.dst_gram_addr = (uint32_t)frame_buffer; pcf.pixelFormat = PCF_PIXEL_FORMAT_RGB565; pcf.size = 12; pcf.color = WHITE; pcf.colorShadow = GRAY; pcf.alphaSoftBlending = 1; pcf.enableShadow = 1; pcf_font.metrics.hSpacing = 2; char s[10]; SPRINTF(s, "%d/%d", id, fat.fileCnt - 1); LCD_GotoXY(5, MUSIC_INFO_POS_Y + 1); LCDPutString(s, &pcf); DRAW_MOV_TIME_STR(); DRAW_MOV_REMAIN_TIME_STR(); LCD_FRAME_BUFFER_Transmit(LCD_DMA_TRANSMIT_BLOCKING); }
size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags) { size_t writtenbytes =0; my_off_t seekptr; #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) uint errors; #endif DBUG_ENTER("my_fwrite"); DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %d", (long) stream, (long) Buffer, (uint) Count, MyFlags)); #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) errors=0; #endif seekptr= ftell(stream); for (;;) { size_t written; if ((written = (size_t) fwrite((char*) Buffer,sizeof(char), Count, stream)) != Count) { DBUG_PRINT("error",("Write only %d bytes", (int) writtenbytes)); my_errno=errno; if (written != (size_t) -1) { seekptr+=written; Buffer+=written; writtenbytes+=written; Count-=written; } #ifdef EINTR if (errno == EINTR) { VOID(my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0))); continue; } #endif #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) #ifdef THREAD if (my_thread_var->abort) MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */ #endif if ((errno == ENOSPC || errno == EDQUOT) && (MyFlags & MY_WAIT_IF_FULL)) { wait_for_free_space("[stream]", errors); errors++; VOID(my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0))); continue; } #endif if (ferror(stream) || (MyFlags & (MY_NABP | MY_FNABP))) { if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG), my_filename(fileno(stream)),errno); } writtenbytes= (size_t) -1; /* Return that we got error */ break; } } if (MyFlags & (MY_NABP | MY_FNABP)) writtenbytes= 0; /* Everything OK */ else writtenbytes+= written; break; } DBUG_RETURN(writtenbytes); } /* my_fwrite */
int main(int argc, char **argv) { char *input_dir, *output_dir; if(argc != 3) { usage(argc, argv); return EXIT_FAILURE; } else { input_dir = argv[1]; output_dir = argv[2]; } if(strcmp(input_dir, output_dir) == 0) { fprintf(stderr,"ERROR: Input and output directories are the same..exiting\n"); return EXIT_FAILURE; } struct timeval tstart, tend; gettimeofday(&tstart, NULL); char locations_filename[MAXLEN], forests_filename[MAXLEN]; int64_t *forests=NULL, *tree_roots=NULL; my_snprintf(locations_filename, MAXLEN, "%s/locations.dat", input_dir); my_snprintf(forests_filename, MAXLEN, "%s/forests.list", input_dir); fprintf(stderr, ANSI_COLOR_MAGENTA"Reading forests...."ANSI_COLOR_RESET"\n"); const int64_t ntrees = read_forests(forests_filename, &forests, &tree_roots); fprintf(stderr, ANSI_COLOR_GREEN"Reading forests......done"ANSI_COLOR_RESET"\n\n"); /* fprintf(stderr, "Number of trees = %"PRId64"\n\n",ntrees); */ struct locations *locations = my_malloc(sizeof(*locations), ntrees); int nfiles = 0, BOX_DIVISIONS=0; fprintf(stderr, ANSI_COLOR_MAGENTA"Reading locations...."ANSI_COLOR_RESET"\n"); const int64_t ntrees_loc = read_locations(locations_filename, ntrees, locations, &nfiles, &BOX_DIVISIONS); fprintf(stderr, ANSI_COLOR_GREEN"Reading locations......done"ANSI_COLOR_RESET"\n\n"); XASSERT(ntrees == ntrees_loc, "ntrees=%"PRId64" should be equal to ntrees_loc=%"PRId64"\n", ntrees, ntrees_loc); /* the following function will sort locations and forests based on tree root id*/ assign_forest_ids(ntrees, locations, forests, tree_roots); /* Forests are now contained inside locations -> free the pointers */ free(forests);free(tree_roots); FILE **tree_outputs = my_malloc(sizeof(FILE *), nfiles); FILE **tree_inputs = my_malloc(sizeof(FILE *), nfiles); int *tree_inputs_fd = my_malloc(sizeof(*tree_inputs_fd), nfiles); int *tree_outputs_fd = my_malloc(sizeof(*tree_outputs_fd), nfiles); XASSERT(sizeof(off_t) == 8, "File offset bits must be 64\n" "Please ensure "ANSI_COLOR_RED"#define _FILE_OFFSET_BITS 64"ANSI_COLOR_RESET" is present\n"); off_t *tree_outputs_fd_offset = my_malloc(sizeof(*tree_outputs_fd_offset), nfiles); int64_t *tree_counts = my_calloc(sizeof(*tree_counts), nfiles); int64_t *inp_file_sizes = my_calloc(sizeof(*inp_file_sizes), nfiles); char buffer[MAXLEN]; for (int i=0; i<BOX_DIVISIONS; i++) { for (int j=0; j<BOX_DIVISIONS; j++) { for(int k=0; k<BOX_DIVISIONS; k++) { my_snprintf(buffer,MAXLEN,"%s/tree_%d_%d_%d.dat", input_dir, i, j, k); int id = id = i*BOX_DIVISIONS*BOX_DIVISIONS + j*BOX_DIVISIONS + k; tree_inputs[id] = my_fopen(buffer, "r"); XASSERT(setvbuf(tree_inputs[id], NULL, _IONBF, 0) == 0, "Could not set unbuffered fgets"); my_fseek(tree_inputs[id],0L, SEEK_END); inp_file_sizes[id] = ftello(tree_inputs[id]); rewind(tree_inputs[id]); tree_inputs_fd[id] = fileno(tree_inputs[id]); my_snprintf(buffer,MAXLEN,"%s/tree_%d_%d_%d.dat", output_dir, i, j, k); unlink(buffer); tree_outputs[id] = my_fopen(buffer, "w"); /* setbuf(tree_outputs[id], _IOFBF); */ tree_outputs_fd[id] = fileno(tree_outputs[id]); } } } /* the following function will sort locations based on 1) filename 2) offsets */ sort_locations_file_offset(ntrees, locations); /* holder to check later that bytes have been assigned */ for(int64_t i=0;i<ntrees;i++) { locations[i].bytes = -1;/* Make sure bytes is a signed type! */ } /* Create a copy of current locations */ struct locations *new_locations = my_malloc(sizeof(*new_locations), ntrees); assert(sizeof(*new_locations) == sizeof(*locations) && "locations struct is varying in size! The sky is falling!!"); memcpy(new_locations, locations, sizeof(*locations) * ntrees); /* figure out the byte size for each tree */ int64_t start = locations[0].offset; int64_t start_fileid = locations[0].fileid; /* tree_roots are 64 bit integers -> max digits in decimal = log10(2^64) < 20. Add 1 char for +-, in case consistent tree changes. and then strlen('#tree ') and the previous \n. I need to read up to previous newline. */ const int64_t guess_max_linesize = 20 + 1 + 6 + 1; fprintf(stderr, ANSI_COLOR_MAGENTA"Calculating the number of bytes for each tree...."ANSI_COLOR_RESET"\n"); /* setup the progressbar */ int interrupted=0; init_my_progressbar(ntrees, &interrupted); for(int64_t i=1;i<=ntrees-1;i++) { my_progressbar(i, &interrupted); const int64_t fileid = locations[i].fileid; /* Are we starting on a new file ?*/ if(start_fileid != fileid) { /* fill out the bytes for the last tree in the previous file */ const int64_t num_bytes = compute_numbytes_with_off(inp_file_sizes[start_fileid], start); locations[i-1].bytes = num_bytes; new_locations[i-1].bytes = num_bytes; /* now we reset the start fields */ start = locations[i].offset; start_fileid = locations[i].fileid; continue; } const int64_t current_offset_guess = locations[i].offset - guess_max_linesize; my_fseek(tree_inputs[fileid], current_offset_guess, SEEK_SET); while(1) { const int a = fgetc(tree_inputs[fileid]); if(a == EOF) { fprintf(stderr,"Encountered EOF while looking for end of current tree\n"); exit(EXIT_FAILURE); } const unsigned char c = (unsigned char) a; if(c == '\n') { const int64_t num_bytes = compute_numbytes(tree_inputs[start_fileid], start); locations[i-1].bytes = num_bytes; new_locations[i-1].bytes = num_bytes; /* fprintf(stderr,"%"PRId64"\n",num_bytes); */ start = locations[i].offset; break; } } } /* fill out the bytes for the last tree */ { start = locations[ntrees-1].offset; const int64_t fileid = locations[ntrees-1].fileid; my_fseek(tree_inputs[fileid], 0L, SEEK_END); const int64_t num_bytes = compute_numbytes(tree_inputs[fileid], start); locations[ntrees-1].bytes = num_bytes; new_locations[ntrees-1].bytes = num_bytes; } finish_myprogressbar(&interrupted); fprintf(stderr, ANSI_COLOR_GREEN"Calculating the number of bytes for each tree.....done"ANSI_COLOR_RESET"\n\n"); for(int64_t i=ntrees-1;i>=0;i--) { XASSERT(locations[i].bytes > 0, "locations[%"PRId64"].bytes = %"PRId64" should be positive\n", i,locations[i].bytes); XASSERT(new_locations[i].bytes == locations[i].bytes, "locations[%"PRId64"].bytes = %"PRId64" should be equal new_locations->bytes = %"PRId64"\n", i,locations[i].bytes,new_locations[i].bytes); XASSERT(strncmp(new_locations[i].filename, locations[i].filename, LOCATIONS_FILENAME_SIZE) == 0, "new_locations[%"PRId64"].filename = %s should equal locations filename = %s\n", i, new_locations[i].filename, locations[i].filename); assert(new_locations[i].forestid == locations[i].forestid); assert(new_locations[i].tree_root == locations[i].tree_root); assert(new_locations[i].fileid == locations[i].fileid); assert(new_locations[i].offset == locations[i].offset); assert(new_locations[i].bytes == locations[i].bytes); /* fprintf(stderr,"locations[%"PRId64"].bytes = %"PRId64"\n", */ /* i,locations[i].bytes); */ } /* Check that the preceeding bytes computation is correct */ { int64_t *total_tree_bytes = my_calloc(sizeof(*total_tree_bytes), nfiles); for(int64_t i=0;i<ntrees;i++) { /* add the number of bytes for tree in each file */ total_tree_bytes[locations[i].fileid] += locations[i].bytes; } for(int i=0;i<nfiles;i++) { XASSERT(total_tree_bytes[i] < inp_file_sizes[i], "Bytes in tree = %"PRId64" must be smaller than file size = %"PRId64"\n", total_tree_bytes[i], inp_file_sizes[i]); } free(total_tree_bytes); } /* Now assign all trees in the same forest to the same file The new fileids goes into new_locations (which is otherwise a copy of locations) */ assign_trees_in_forest_to_same_file(ntrees, locations, new_locations, nfiles, BOX_DIVISIONS); /* Now write out both the old and the new struct locations */ my_snprintf(buffer, MAXLEN, "%s/forests_and_locations_old.list",output_dir); write_forests_and_locations(buffer, ntrees, locations); /* write new the forests file */ my_snprintf(buffer,MAXLEN,"%s/forests.list", output_dir); unlink(buffer); FILE *fp_forests = my_fopen(buffer,"w"); fprintf(fp_forests, "#TreeRootID ForestID\n"); for(int64_t i=0;i<ntrees;i++) { fprintf(fp_forests, "%"PRId64" %"PRId64"\n", locations[i].tree_root, locations[i].forestid); } fclose(fp_forests); /* open the locations file*/ my_snprintf(buffer,MAXLEN,"%s/locations.dat", output_dir); unlink(buffer); FILE *fp_locations = my_fopen(buffer,"w"); fprintf(fp_locations, "#TreeRootID FileID Offset Filename\n"); /* copy the headers between the tree_* files */ /* break when the number of trees is encountered -- should be the first one line that doesn't have a '#' character at front */ int64_t *tree_header_offsets = my_malloc(sizeof(*tree_header_offsets), nfiles); for(int i=0;i<nfiles;i++) { /* All of the file pointers have been moved around to figure out the bytes -> reposition them at the beginning of the tree_*.dat file */ rewind(tree_inputs[i]); while(fgets(buffer, MAXLEN, tree_inputs[i]) != NULL) { if(buffer[0] != '#') { tree_header_offsets[i] = ftello(tree_outputs[i]); /* write a place holder for the number of trees in the file. There are 18 X's in the following line, DO NOT CHANGE. */ fprintf(tree_outputs[i], "XXXXXXXXXXXXXXXXXX\n"); //For the number of trees break; } else { fprintf(tree_outputs[i], "%s", buffer); } } tree_outputs_fd_offset[i] = ftello(tree_outputs[i]); } /* Figure out the offsets and write out a binary file containing the new locations info */ for(int64_t i=0;i<ntrees;i++) { const int tree_bytes_line_size = my_snprintf(buffer, MAXLEN, "#tree %"PRId64"\n", locations[i].tree_root); const int64_t bytes_to_write = locations[i].bytes; const int64_t out_fileid = new_locations[i].fileid; XASSERT(out_fileid < nfiles, "Output fileid = %"PRId64" must be smaller than total number of files = %d\n" , out_fileid, nfiles); /* XASSERT(new_locations[i].bytes == bytes_to_write, */ /* "new locations bytes = %"PRId64"should be identical to old locations bytes = %"PRId64"\n", */ /* new_locations[i].bytes,bytes_to_write); */ new_locations[i].offset = tree_outputs_fd_offset[out_fileid] + tree_bytes_line_size; tree_outputs_fd_offset[out_fileid] += (bytes_to_write + tree_bytes_line_size); } /* Valgrind complains there is use of uninitialized bytes -> so ditching this binary file output for now */ /* /\* Output the binary locations struct so I can skip over recalculating the bytes *\/ */ /* { */ /* my_snprintf(buffer, MAXLEN, "%s/new_locations.binary",output_dir); */ /* FILE *fp = my_fopen(buffer, "w"); */ /* /\* fprintf(stderr,"ntrees = %"PRId64"\n",ntrees); *\/ */ /* my_fwrite(&ntrees, sizeof(int64_t), 1, fp); */ /* const size_t size_of_struct = sizeof(struct locations); */ /* /\* fprintf(stderr,"struct size = %zu\n", size_of_struct); *\/ */ /* my_fwrite(&size_of_struct, sizeof(size_t), 1, fp); */ /* /\* my_fwrite(new_locations, size_of_struct, ntrees, fp); *\/ */ /* fclose(fp); */ /* } */ /* Write out the combined forests and locations file */ my_snprintf(buffer, MAXLEN, "%s/forests_and_locations_new.list",output_dir); write_forests_and_locations(buffer, ntrees, new_locations); fprintf(stderr, ANSI_COLOR_MAGENTA"Writing out trees in contiguous order...."ANSI_COLOR_RESET"\n"); interrupted=0; init_my_progressbar(ntrees, &interrupted); /* Now copy each one of the trees */ for(int64_t i=0;i<ntrees;i++) { my_progressbar(i, &interrupted); const int64_t fileid = locations[i].fileid; XASSERT(locations[i].tree_root == new_locations[i].tree_root, "locations->tree_root = %"PRId64" must equal new_locations->tree_root = %"PRId64"\n", locations[i].tree_root, new_locations[i].tree_root); XASSERT(locations[i].forestid == new_locations[i].forestid, "locations->forestid = %"PRId64" must equal new_locations->forestid = %"PRId64"\n", locations[i].forestid, new_locations[i].forestid); /* Make sure all output is done using new_locations[i].fileid */ const int64_t out_fileid = new_locations[i].fileid; FILE *out_fp = tree_outputs[out_fileid]; /* const int tree_bytes_line_size = fprintf(out_fp, "#tree %"PRId64"\n", locations[i].tree_root); */ fprintf(out_fp, "#tree %"PRId64"\n", locations[i].tree_root); fflush(out_fp); const int64_t offset = locations[i].offset; const int64_t bytes_to_write = locations[i].bytes; if(bytes_to_write == 0) { fprintf(stderr, "Strange! bytes for tree data = %zu should not be 0\n", bytes_to_write); continue; } #ifdef USE_FGETS //USE_FGETS -> stdio.h family #warning using fgets (slowest) FILE *in_fp = tree_inputs[fileid]; my_fseek(in_fp, (long) offset, SEEK_SET); const long actual_offset = ftello(out_fp); XASSERT(actual_offset == new_locations[i].offset, "actual offset = %ld should equal calculated offset = %"PRId64"\n", actual_offset, new_locations[i].offset); /* new_locations[i].offset = ftello(out_fp); */ const int64_t bytes_written = copy_bytes_between_two_files(bytes_to_write, in_fp, out_fp); #else //use pread/write #warning using pread int in_fd = tree_inputs_fd[fileid]; int out_fd = tree_outputs_fd[out_fileid]; off_t in_offset = offset; const int64_t bytes_written = copy_bytes_with_pread(bytes_to_write, in_fd, out_fd, in_offset); /* I have already figured out the offsets */ /* new_locations[i].offset = tree_outputs_fd_offset[out_fileid] + tree_bytes_line_size; */ #endif//USE_FGETS -> stdio.h family XASSERT(bytes_written == bytes_to_write, "bytes_to_write = %zu does not equal bytes_written = %zu\n", bytes_to_write, bytes_written); /* Update the number of trees in that file */ tree_counts[out_fileid]++; /* write the locations info*/ const int ii = out_fileid/(BOX_DIVISIONS*BOX_DIVISIONS); const int jj = (out_fileid%((int64_t)(BOX_DIVISIONS*BOX_DIVISIONS)))/BOX_DIVISIONS; const int kk = out_fileid%((int64_t)BOX_DIVISIONS); fprintf(fp_locations, "%"PRId64" %"PRId64" %"PRId64" tree_%d_%d_%d.dat\n", new_locations[i].tree_root, out_fileid, new_locations[i].offset, ii, jj, kk); /* This line is only required if offsets have not been computed earlier */ /* tree_outputs_fd_offset[out_fileid] += (bytes_written + tree_bytes_line_size) ; */ } /* fill in the number of trees written per file. the number in the format *MUST EXACTLY* match the number of XXX's in the previous place-holder. */ for(int i=0;i<nfiles;i++) { FILE *out_fp = tree_outputs[i]; fseek(out_fp, tree_header_offsets[i], SEEK_SET); fprintf(out_fp, "%-18"PRId64"\n", tree_counts[i]); } finish_myprogressbar(&interrupted); fprintf(stderr, ANSI_COLOR_GREEN "Writing out trees in contiguous order.....done"ANSI_COLOR_RESET"\n\n"); /* close open file pointers + free memory for file pointers */ fclose(fp_locations); for(int i=0;i<nfiles;i++) { fclose(tree_inputs[i]); fclose(tree_outputs[i]); } free(tree_inputs);free(tree_outputs); free(tree_inputs_fd);free(tree_outputs_fd); /* free other heap allocations */ free(tree_header_offsets); free(tree_outputs_fd_offset); free(tree_counts); free(inp_file_sizes); free(locations); free(new_locations); gettimeofday(&tend, NULL); fprintf(stderr,"Wrote out %"PRId64" trees in contiguous order. Time taken = %0.2g seconds\n", ntrees, ADD_DIFF_TIME(tstart, tend)); return EXIT_SUCCESS; }
uint my_fwrite(FILE *stream, const byte *Buffer, uint Count, myf MyFlags) { uint writenbytes=0; off_t seekptr; #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) uint errors; #endif DBUG_ENTER("my_fwrite"); DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %d", stream, Buffer, Count, MyFlags)); #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) errors=0; #endif seekptr=ftell(stream); for (;;) { uint writen; if ((writen = (uint) fwrite((char*) Buffer,sizeof(char), (size_t) Count, stream)) != Count) { DBUG_PRINT("error",("Write only %d bytes",writenbytes)); my_errno=errno; if (writen != (uint) -1) { seekptr+=writen; Buffer+=writen; writenbytes+=writen; Count-=writen; } #ifdef EINTR if (errno == EINTR) { VOID(my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0))); continue; } #endif #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) #ifdef THREAD if (my_thread_var->abort) MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */ #endif if ((errno == ENOSPC || errno == EDQUOT) && (MyFlags & MY_WAIT_IF_FULL)) { if (!(errors++ % MY_WAIT_GIVE_USER_A_MESSAGE)) my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH), "[stream]",my_errno,MY_WAIT_FOR_USER_TO_FIX_PANIC); VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC)); VOID(my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0))); continue; } #endif if (ferror(stream) || (MyFlags & (MY_NABP | MY_FNABP))) { if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG), my_filename(fileno(stream)),errno); } writenbytes=(uint) -1; /* Return that we got error */ break; } } if (MyFlags & (MY_NABP | MY_FNABP)) writenbytes=0; /* Everything OK */ else writenbytes+=writen; break; } DBUG_RETURN(writenbytes); } /* my_fwrite */
static int create_sys_files(struct languages *lang_head, struct errors *error_head, uint row_count) { FILE *to; uint csnum= 0, length, i, row_nr; uchar head[32]; char outfile[FN_REFLEN], *outfile_end; long start_pos; struct message *tmp; struct languages *tmp_lang; struct errors *tmp_error; MY_STAT stat_info; DBUG_ENTER("create_sys_files"); /* going over all languages and assembling corresponding error messages */ for (tmp_lang= lang_head; tmp_lang; tmp_lang= tmp_lang->next_lang) { /* setting charset name */ if (!(csnum= get_charset_number(tmp_lang->charset, MY_CS_PRIMARY))) { fprintf(stderr, "Unknown charset '%s' in '%s'\n", tmp_lang->charset, TXTFILE); DBUG_RETURN(1); } outfile_end= strxmov(outfile, DATADIRECTORY, tmp_lang->lang_long_name, NullS); if (!my_stat(outfile, &stat_info,MYF(0))) { if (my_mkdir(outfile, 0777,MYF(0)) < 0) { fprintf(stderr, "Can't create output directory for %s\n", outfile); DBUG_RETURN(1); } } strxmov(outfile_end, FN_ROOTDIR, OUTFILE, NullS); if (!(to= my_fopen(outfile, O_WRONLY | FILE_BINARY, MYF(MY_WME)))) DBUG_RETURN(1); /* 4 is for 4 bytes to store row position / error message */ start_pos= (long) (HEADER_LENGTH + row_count * 4); fseek(to, start_pos, 0); row_nr= 0; for (tmp_error= error_head; tmp_error; tmp_error= tmp_error->next_error) { /* dealing with messages */ tmp= find_message(tmp_error, tmp_lang->lang_short_name, FALSE); if (!tmp) { fprintf(stderr, "Did not find message for %s neither in %s nor in default " "language\n", tmp_error->er_name, tmp_lang->lang_short_name); goto err; } if (copy_rows(to, tmp->text, row_nr, start_pos)) { fprintf(stderr, "Failed to copy rows to %s\n", outfile); goto err; } row_nr++; } /* continue with header of the errmsg.sys file */ length= ftell(to) - HEADER_LENGTH - row_count * 4; memset(head, 0, HEADER_LENGTH); memmove(head, file_head, 4); head[4]= 1; int4store(head + 6, length); int4store(head + 10, row_count); head[30]= csnum; my_fseek(to, 0l, MY_SEEK_SET, MYF(0)); if (my_fwrite(to, (uchar*) head, HEADER_LENGTH, MYF(MY_WME | MY_FNABP))) goto err; for (i= 0; i < row_count; i++) { int4store(head, file_pos[i]); if (my_fwrite(to, (uchar*) head, 4, MYF(MY_WME | MY_FNABP))) goto err; } my_fclose(to, MYF(0)); } DBUG_RETURN(0); err: my_fclose(to, MYF(0)); DBUG_RETURN(1); }
static void file_check_doc(file_recovery_t *file_recovery) { unsigned char buffer_header[512]; uint64_t doc_file_size; uint32_t *fat; unsigned long int i; unsigned int freesect_count=0; const struct OLE_HDR *header=(const struct OLE_HDR*)&buffer_header; const uint64_t doc_file_size_org=file_recovery->file_size; file_recovery->file_size=0; /*reads first sector including OLE header */ if(my_fseek(file_recovery->handle, 0, SEEK_SET) < 0 || fread(&buffer_header, sizeof(buffer_header), 1, file_recovery->handle) != 1) return ; #ifdef DEBUG_OLE log_info("file_check_doc %s\n", file_recovery->filename); log_trace("sector size %u\n",1<<le16(header->uSectorShift)); log_trace("num_FAT_blocks %u\n",le32(header->num_FAT_blocks)); log_trace("num_extra_FAT_blocks %u\n",le32(header->num_extra_FAT_blocks)); #endif /* Sanity check */ if(le32(header->num_FAT_blocks)==0 || le32(header->num_extra_FAT_blocks)>50 || le32(header->num_FAT_blocks)>109+le32(header->num_extra_FAT_blocks)*((1<<le16(header->uSectorShift))-1)) return ; if((fat=OLE_load_FAT(file_recovery->handle, header))==NULL) { #ifdef DEBUG_OLE log_info("OLE_load_FAT failed\n"); #endif return ; } /* Search how many entries are not used at the end of the FAT */ for(i=(le32(header->num_FAT_blocks)<<le16(header->uSectorShift))/4-1; i>0 && le32(fat[i])==0xFFFFFFFF; i--) freesect_count++; doc_file_size=((1+(le32(header->num_FAT_blocks)<<le16(header->uSectorShift))/4-freesect_count)<<le16(header->uSectorShift)); if(doc_file_size > doc_file_size_org) { #ifdef DEBUG_OLE log_info("doc_file_size=(1+(%u<<%u)/4-%u)<<%u\n", le32(header->num_FAT_blocks), le16(header->uSectorShift), freesect_count, le16(header->uSectorShift)); log_info("doc_file_size %llu > doc_file_size_org %llu\n", (unsigned long long)doc_file_size, (unsigned long long)doc_file_size_org); #endif free(fat); return ; } #ifdef DEBUG_OLE log_trace("==> size : %llu\n", (long long unsigned)doc_file_size); #endif { unsigned int block; const unsigned int fat_entries=(le32(header->num_FAT_blocks)==0 ? 109: (le32(header->num_FAT_blocks)<<le16(header->uSectorShift))/4); #ifdef DEBUG_OLE log_info("root_start_block=%u, fat_entries=%u\n", le32(header->root_start_block), fat_entries); #endif /* FFFFFFFE = ENDOFCHAIN * Use a loop count i to avoid endless loop */ for(block=le32(header->root_start_block), i=0; block!=0xFFFFFFFE && i<fat_entries; block=le32(fat[block]), i++) { struct OLE_DIR *dir_entries; #ifdef DEBUG_OLE log_info("read block %u\n", block); #endif if(!(block < fat_entries)) { free(fat); return ; } if(my_fseek(file_recovery->handle, (1+block)<<le16(header->uSectorShift), SEEK_SET)<0) { #ifdef DEBUG_OLE log_info("fseek failed\n"); #endif free(fat); return ; } dir_entries=(struct OLE_DIR *)MALLOC(1<<le16(header->uSectorShift)); if(fread(dir_entries, (1<<le16(header->uSectorShift)), 1, file_recovery->handle)!=1) { #ifdef DEBUG_OLE log_info("fread failed\n"); #endif free(dir_entries); free(fat); return ; } { unsigned int sid; struct OLE_DIR *dir_entry; for(sid=0, dir_entry=dir_entries; sid<(1<<le16(header->uSectorShift))/sizeof(struct OLE_DIR) && dir_entry->type!=NO_ENTRY; sid++,dir_entry++) { if(le32(dir_entry->start_block) > 0 && le32(dir_entry->size) > 0 && ((le32(dir_entry->size) >= le32(header->miniSectorCutoff) && le32(dir_entry->start_block) > fat_entries) || le32(dir_entry->size) > doc_file_size)) { #ifdef DEBUG_OLE log_info("error at sid %u\n", sid); #endif free(dir_entries); free(fat); return ; } } } free(dir_entries); } } free(fat); file_recovery->file_size=doc_file_size; }
int PlaySoundPhotoFrame(int id) { int ret; WAVEFormatStruct wav; WAVEFormatHeaderStruct wavHeader; WAVEFormatChunkStruct wavChunk; char str[10]; NVIC_InitTypeDef NVIC_InitStructure; MY_FILE *infile; if(!(infile = my_fopen(id))){ ret = RET_PLAY_STOP; goto EXIT_WAV; } my_fread(&wavHeader, 1, sizeof(WAVEFormatHeaderStruct), infile); debug.printf("\r\n\n[WAVE]"); if(strncmp(wavHeader.headStrRIFF, "RIFF", 4) != 0){ debug.printf("\r\nNot contain RIFF chunk"); ret = RET_PLAY_STOP; goto END_WAV; } debug.printf("\r\nFile Size:%d", wavHeader.fileSize); if(strncmp(wavHeader.headStrWAVE, "WAVE", 4) != 0){ debug.printf("\r\nThis is not WAVE file."); ret = RET_PLAY_STOP; goto END_WAV; } int restBytes = wavHeader.fileSize; while(1){ // loop until format chunk is found my_fread(&wavChunk, 1, sizeof(WAVEFormatChunkStruct), infile); if(strncmp(wavChunk.chunkfmt, "fmt ", 4) == 0){ break; } memset(str, '\0', sizeof(str)); debug.printf("\r\n\nchunkType:%s", strncpy(str, wavChunk.chunkfmt, sizeof(wavChunk.chunkfmt))); debug.printf("\r\nchunkSize:%d", wavChunk.chunkSize); restBytes = restBytes - wavChunk.chunkSize - sizeof(WAVEFormatChunkStruct); if(restBytes <= 0){ debug.printf("\r\nNot Found Format Chunk."); ret = RET_PLAY_STOP; goto END_WAV; } my_fseek(infile, wavChunk.chunkSize, SEEK_CUR); } my_fread(&wav, 1, sizeof(WAVEFormatStruct), infile); my_fseek(infile, wavChunk.chunkSize - sizeof(WAVEFormatStruct), SEEK_CUR); restBytes = restBytes - wavChunk.chunkSize - sizeof(WAVEFormatChunkStruct); while(1){ // loop until data chunk is found my_fread(&wavChunk, 1, sizeof(WAVEFormatChunkStruct), infile); if(strncmp(wavChunk.chunkfmt, "data", 4) == 0){ break; } memset(str, '\0', sizeof(str)); debug.printf("\r\n\nchunkType:%s", strncpy(str, wavChunk.chunkfmt, sizeof(wavChunk.chunkfmt))); debug.printf("\r\nchunkSize:%d", wavChunk.chunkSize); restBytes = restBytes - wavChunk.chunkSize - sizeof(WAVEFormatChunkStruct); if(restBytes <= 0){ debug.printf("\r\nNot Found Format Chunk."); ret = RET_PLAY_STOP; goto END_WAV; } my_fseek(infile, wavChunk.chunkSize, SEEK_CUR); } memset(str, '\0', sizeof(str)); debug.printf("\r\n\nchunkType:%s", strncpy(str, wavChunk.chunkfmt, sizeof(wavChunk.chunkfmt))); debug.printf("\r\nchunkSize:%d", wavChunk.chunkSize); debug.printf("\r\n\nformatID:%d", wav.formatID); debug.printf("\r\nNum Channel:%d", wav.numChannel); debug.printf("\r\nSampling Rate:%d", wav.sampleRate); debug.printf("\r\nData Speed:%d", wav.dataSpeed); debug.printf("\r\nBlock Size:%d", wav.blockSize); debug.printf("\r\nBit Per Sample:%d", wav.bitPerSample); debug.printf("\r\nBytes Wave Data:%d", wavChunk.chunkSize); dac_intr.fp = infile; dac_intr.buff = (uint8_t*)cursorRAM;//SOUND_BUFFER; dac_intr.bufferSize = sizeof(cursorRAM); dac_intr.contentSize = infile->fileSize - infile->seekBytes; dac_intr.comp = 0; my_fread(dac_intr.buff, 1, dac_intr.bufferSize, dac_intr.fp); dac_intr.sound_reads = dac_intr.bufferSize; if(wav.bitPerSample == 8){ dac_intr.func = DAC_Buffer_Process_Mono_U8bit; } else { dac_intr.func = DAC_Buffer_Process_Stereo_S16bit_PhotoFrame; } RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); // Enable DMA1_Stream1 gloabal Interrupt NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); SOUNDInitDAC(wav.sampleRate); SOUNDDMAConf((void*)&DAC->DHR12LD, wav.blockSize, (wav.bitPerSample / 8) * wav.numChannel); DMA_ITConfig(DMA1_Stream1, DMA_IT_TC | DMA_IT_HT, ENABLE); DMA_Cmd(DMA1_Stream1, ENABLE); END_WAV: EXIT_WAV: /* Disable DMA1_Stream1 gloabal Interrupt */ // NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream1_IRQn; // NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; // NVIC_Init(&NVIC_InitStructure); // my_fclose(infile); return 0; }
int PlaySound(int id) { time.flags.enable = 0; TouchPenIRQ_Disable(); TOUCH_PINIRQ_DISABLE; touch.func = touch_empty_func; int i; uint32_t *pabuf; uint8_t *outbuf; char str[10]; int totalSec, remainTotalSec, media_data_totalBytes; int curX = 0, prevX = 0; volatile int ret = RET_PLAY_NORM; NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; void *putCharTmp = '\0', *putWideCharTmp = '\0'; drawBuff_typedef dbuf, *drawBuff; drawBuff = &dbuf; _drawBuff = drawBuff; char timeStr[20]; WAVEFormatStruct wav; WAVEFormatHeaderStruct wavHeader; WAVEFormatChunkStruct wavChunk; MY_FILE *infile, file_covr; if(!(infile = my_fopen(id))){ ret = RET_PLAY_STOP; goto EXIT_WAV; } my_fread(&wavHeader, 1, sizeof(WAVEFormatHeaderStruct), infile); debug.printf("\r\n\n[WAVE]"); if(strncmp(wavHeader.headStrRIFF, "RIFF", 4) != 0){ debug.printf("\r\nNot contain RIFF chunk"); ret = RET_PLAY_STOP; goto END_WAV; } debug.printf("\r\nFile Size:%d", wavHeader.fileSize); if(strncmp(wavHeader.headStrWAVE, "WAVE", 4) != 0){ debug.printf("\r\nThis is not WAVE file."); ret = RET_PLAY_STOP; goto END_WAV; } int restBytes = wavHeader.fileSize; while(1){ // loop until format chunk is found my_fread(&wavChunk, 1, sizeof(WAVEFormatChunkStruct), infile); if(strncmp(wavChunk.chunkfmt, "fmt ", 4) == 0){ break; } memset(str, '\0', sizeof(str)); debug.printf("\r\n\nchunkType:%s", strncpy(str, wavChunk.chunkfmt, sizeof(wavChunk.chunkfmt))); debug.printf("\r\nchunkSize:%d", wavChunk.chunkSize); restBytes = restBytes - wavChunk.chunkSize - sizeof(WAVEFormatChunkStruct); if(restBytes <= 0){ debug.printf("\r\nNot Found Format Chunk."); ret = RET_PLAY_STOP; goto END_WAV; } my_fseek(infile, wavChunk.chunkSize, SEEK_CUR); } my_fread(&wav, 1, sizeof(WAVEFormatStruct), infile); my_fseek(infile, wavChunk.chunkSize - sizeof(WAVEFormatStruct), SEEK_CUR); restBytes = restBytes - wavChunk.chunkSize - sizeof(WAVEFormatChunkStruct); while(1){ // loop until data chunk is found my_fread(&wavChunk, 1, sizeof(WAVEFormatChunkStruct), infile); if(strncmp(wavChunk.chunkfmt, "data", 4) == 0){ break; } memset(str, '\0', sizeof(str)); debug.printf("\r\n\nchunkType:%s", strncpy(str, wavChunk.chunkfmt, sizeof(wavChunk.chunkfmt))); debug.printf("\r\nchunkSize:%d", wavChunk.chunkSize); restBytes = restBytes - wavChunk.chunkSize - sizeof(WAVEFormatChunkStruct); if(restBytes <= 0){ debug.printf("\r\nNot Found Format Chunk."); ret = RET_PLAY_STOP; goto END_WAV; } my_fseek(infile, wavChunk.chunkSize, SEEK_CUR); } music_src_p.curX = &curX; music_src_p.prevX = &prevX; music_src_p.media_data_totalBytes = &media_data_totalBytes; music_src_p.totalSec = &totalSec; music_src_p.drawBuff = drawBuff; music_src_p.fp = infile; LCDPutBgImgMusic(); file_covr.clusterOrg = 0; dispArtWork(&file_covr); LCDPutIcon(0, 155, 320, 80, music_underbar_320x80, music_underbar_320x80_alpha); memset(str, '\0', sizeof(str)); debug.printf("\r\n\nchunkType:%s", strncpy(str, wavChunk.chunkfmt, sizeof(wavChunk.chunkfmt))); debug.printf("\r\nchunkSize:%d", wavChunk.chunkSize); debug.printf("\r\n\nformatID:%d", wav.formatID); debug.printf("\r\nNum Channel:%d", wav.numChannel); debug.printf("\r\nSampling Rate:%d", wav.sampleRate); debug.printf("\r\nData Speed:%d", wav.dataSpeed); debug.printf("\r\nBlock Size:%d", wav.blockSize); debug.printf("\r\nBit Per Sample:%d", wav.bitPerSample); debug.printf("\r\nBytes Wave Data:%d", wavChunk.chunkSize); uint32_t data_offset = infile->seekBytes; if(wav.bitPerSample != 16){ debug.printf("\r\n**Bit Per Sample must be 16bit**"); debug.printf("\r\ndata offset:%d", data_offset); ret = RET_PLAY_STOP; goto END_WAV; } int xTag = 110, yTag = 87, disp_limit = 300, strLen; putCharTmp = LCD_FUNC.putChar; putWideCharTmp = LCD_FUNC.putWideChar; if(!pcf_font.c_loaded){ LCD_FUNC.putChar = PCFPutChar16px; LCD_FUNC.putWideChar = PCFPutChar16px; } else { LCD_FUNC.putChar = C_PCFPutChar16px; LCD_FUNC.putWideChar = C_PCFPutChar16px; } disp_limit = 288; uint8_t strNameLFN[80]; if(setLFNname(strNameLFN, id, LFN_WITHOUT_EXTENSION, sizeof(strNameLFN))){ strLen = LCDGetStringLFNPixelLength(strNameLFN, 16); if((xTag + strLen) < LCD_WIDTH){ disp_limit = LCD_WIDTH - 1; } else { disp_limit = LCD_WIDTH - 20; yTag -= 10; } LCDGotoXY(xTag + 1, yTag + 1); LCDPutStringLFN(xTag + 1, disp_limit, 2, strNameLFN, BLACK); LCDGotoXY(xTag, yTag); LCDPutStringLFN(xTag, disp_limit - 1, 2, strNameLFN, WHITE); } else { char strNameSFN[9]; memset(strNameSFN, '\0', sizeof(strNameSFN)); setSFNname(strNameSFN, id); LCDGotoXY(xTag + 1, yTag + 1); LCDPutString(strNameSFN, BLACK); LCDGotoXY(xTag, yTag); LCDPutString(strNameSFN, WHITE); } LCD_FUNC.putChar = putCharTmp; LCD_FUNC.putWideChar = putWideCharTmp; char s[20]; SPRINTF((char*)s, "%d/%d", id, fat.fileCnt - 1); LCDGotoXY(21, MUSIC_INFO_POS_Y + 1); LCDPutString((char*)s, BLACK); LCDGotoXY(20, MUSIC_INFO_POS_Y); LCDPutString((char*)s, WHITE); if(settings_group.music_conf.b.musicinfo){ LCDGotoXY(71, MUSIC_INFO_POS_Y + 1); LCDPutString("WAV", BLACK); LCDGotoXY(70, MUSIC_INFO_POS_Y); LCDPutString("WAV", WHITE); LCDGotoXY(111, MUSIC_INFO_POS_Y + 1); LCDPutString(wav.numChannel == 2 ? "Stereo" : "Mono", BLACK); LCDGotoXY(110, MUSIC_INFO_POS_Y); LCDPutString(wav.numChannel == 2 ? "Stereo" : "Mono", WHITE); SPRINTF(s, "%1.2fMbps", (float)(wav.dataSpeed * 8) / 1000000.0f); LCDGotoXY(171, MUSIC_INFO_POS_Y + 1); LCDPutString(s, BLACK); LCDGotoXY(170, MUSIC_INFO_POS_Y); LCDPutString(s, WHITE); SPRINTF(s, "%dHz", (int)wav.sampleRate); LCDGotoXY(241, MUSIC_INFO_POS_Y + 1); LCDPutString(s, BLACK); LCDGotoXY(240, MUSIC_INFO_POS_Y); LCDPutString(s, WHITE); } putCharTmp = LCD_FUNC.putChar; putWideCharTmp = LCD_FUNC.putWideChar; if(!pcf_font.c_loaded){ LCD_FUNC.putChar = PCFPutCharCache; LCD_FUNC.putWideChar = PCFPutCharCache; extern uint16_t cursorRAM[]; PCFSetGlyphCacheStartAddress((void*)cursorRAM); PCFCachePlayTimeGlyphs(12); } else { LCD_FUNC.putChar = C_PCFPutChar; LCD_FUNC.putWideChar = C_PCFPutChar; } media_data_totalBytes = wavChunk.chunkSize; totalSec = wavChunk.chunkSize / wav.dataSpeed; setStrSec(timeStr, totalSec); debug.printf("\r\nplay time:%s", timeStr); // time elapsed drawBuff->timeElapsed.x = 14; drawBuff->timeElapsed.y = 188; drawBuff->timeElapsed.width = 50; drawBuff->timeElapsed.height = 13; LCDStoreBgImgToBuff(drawBuff->timeElapsed.x, drawBuff->timeElapsed.y, \ drawBuff->timeElapsed.width, drawBuff->timeElapsed.height, drawBuff->timeElapsed.p); // time remain drawBuff->timeRemain.x = totalSec < 6000 ? 268 : 260; drawBuff->timeRemain.y = 188; drawBuff->timeRemain.width = 50; drawBuff->timeRemain.height = 13; LCDStoreBgImgToBuff(drawBuff->timeRemain.x, drawBuff->timeRemain.y, \ drawBuff->timeRemain.width, drawBuff->timeRemain.height, drawBuff->timeRemain.p); drawBuff->posision.x = 0; drawBuff->posision.y = 168; drawBuff->posision.width = 16; drawBuff->posision.height = 16; LCDStoreBgImgToBuff(drawBuff->posision.x, drawBuff->posision.y, \ drawBuff->posision.width, drawBuff->posision.height, drawBuff->posision.p); drawBuff->navigation.x = 142; drawBuff->navigation.y = 189; drawBuff->navigation.width = 32; drawBuff->navigation.height = 32; LCDStoreBgImgToBuff(drawBuff->navigation.x, drawBuff->navigation.y, \ drawBuff->navigation.width, drawBuff->navigation.height, drawBuff->navigation.p); drawBuff->fft_analyzer_left.x = FFT_ANALYZER_LEFT_POS_X; drawBuff->fft_analyzer_left.y = FFT_ANALYZER_LEFT_POS_Y; drawBuff->fft_analyzer_left.width = 32; drawBuff->fft_analyzer_left.height = 32; LCDStoreBgImgToBuff(drawBuff->fft_analyzer_left.x, drawBuff->fft_analyzer_left.y, \ drawBuff->fft_analyzer_left.width, drawBuff->fft_analyzer_left.height, drawBuff->fft_analyzer_left.p); drawBuff->fft_analyzer_right.x = FFT_ANALYZER_RIGHT_POS_X; drawBuff->fft_analyzer_right.y = FFT_ANALYZER_RIGHT_POS_Y; drawBuff->fft_analyzer_right.width = 32; drawBuff->fft_analyzer_right.height = 32; LCDStoreBgImgToBuff(drawBuff->fft_analyzer_right.x, drawBuff->fft_analyzer_right.y, \ drawBuff->fft_analyzer_right.width, drawBuff->fft_analyzer_right.height, drawBuff->fft_analyzer_right.p); drawBuff->navigation_loop.x = 277; drawBuff->navigation_loop.y = 207; drawBuff->navigation_loop.width = 24; drawBuff->navigation_loop.height = 18; LCDStoreBgImgToBuff(drawBuff->navigation_loop.x, drawBuff->navigation_loop.y, \ drawBuff->navigation_loop.width, drawBuff->navigation_loop.height, drawBuff->navigation_loop.p); switch(navigation_loop_mode){ case NAV_ONE_PLAY_EXIT: // 1 play exit LCDPutIcon(_drawBuff->navigation_loop.x, _drawBuff->navigation_loop.y, _drawBuff->navigation_loop.width, _drawBuff->navigation_loop.height, \ navigation_bar_24x18, navigation_bar_24x18_alpha); break; case NAV_PLAY_ENTIRE: // play entire in directry LCDPutIcon(_drawBuff->navigation_loop.x, _drawBuff->navigation_loop.y, _drawBuff->navigation_loop.width, _drawBuff->navigation_loop.height, \ navigation_entire_loop_24x18, navigation_entire_loop_24x18_alpha); break; case NAV_INFINITE_PLAY_ENTIRE: // infinite play entire in directry LCDPutIcon(_drawBuff->navigation_loop.x, _drawBuff->navigation_loop.y, _drawBuff->navigation_loop.width, _drawBuff->navigation_loop.height, \ navigation_infinite_entire_loop_24x18, navigation_infinite_entire_loop_24x18_alpha); break; case NAV_INFINITE_ONE_PLAY: // infinite 1 play LCDPutIcon(_drawBuff->navigation_loop.x, _drawBuff->navigation_loop.y, _drawBuff->navigation_loop.width, _drawBuff->navigation_loop.height, \ navigation_one_loop_24x18, navigation_one_loop_24x18_alpha); break; case NAV_SHUFFLE_PLAY: // shuffle LCDPutIcon(_drawBuff->navigation_loop.x, _drawBuff->navigation_loop.y, _drawBuff->navigation_loop.width, _drawBuff->navigation_loop.height, \ navigation_shuffle_24x18, navigation_shuffle_24x18_alpha); break; default: break; } LCDPutIcon(drawBuff->navigation.x, drawBuff->navigation.y, \ drawBuff->navigation.width, drawBuff->navigation.height, \ navigation_pause_patch_32x32, navigation_pause_patch_32x32_alpha); /* Update Bass Boost Icon */ drawBuff->bass_boost.x = 10; drawBuff->bass_boost.y = 3; drawBuff->bass_boost.width = 24; drawBuff->bass_boost.height = 18; LCDStoreBgImgToBuff(drawBuff->bass_boost.x, drawBuff->bass_boost.y, \ drawBuff->bass_boost.width, drawBuff->bass_boost.height, drawBuff->bass_boost.p); Update_Bass_Boost_Icon(bass_boost_mode); /* Update Reverb Effect Icon */ drawBuff->reverb_effect.x = 60; drawBuff->reverb_effect.y = 2; drawBuff->reverb_effect.width = 24; drawBuff->reverb_effect.height = 18; LCDStoreBgImgToBuff(drawBuff->reverb_effect.x, drawBuff->reverb_effect.y, \ drawBuff->reverb_effect.width, drawBuff->reverb_effect.height, drawBuff->reverb_effect.p); Update_Reverb_Effect_Icon(reverb_effect_mode); /* Update Vocal Canceler Icon */ drawBuff->vocal_cancel.x = 107; drawBuff->vocal_cancel.y = 5; drawBuff->vocal_cancel.width = 24; drawBuff->vocal_cancel.height = 18; LCDStoreBgImgToBuff(drawBuff->vocal_cancel.x, drawBuff->vocal_cancel.y, \ drawBuff->vocal_cancel.width, drawBuff->vocal_cancel.height, drawBuff->vocal_cancel.p); Update_Vocal_Canceler_Icon(vocal_cancel_mode); uint8_t SOUND_BUFFER[9216]; dac_intr.fp = infile; dac_intr.buff = SOUND_BUFFER; dac_intr.bufferSize = sizeof(SOUND_BUFFER); int SoundDMAHalfBlocks = (dac_intr.bufferSize / (sizeof(int16_t) * 2)) / 2; int loop_icon_touched = 0, loop_icon_cnt = 0, boost = 0; int delay_buffer_filled = 0, DMA_Half_Filled = 0; float *fabuf, *fbbuf; float *float_buf = (float*)mempool; int fbuf_len = dac_intr.bufferSize / 2; memset(float_buf, '\0', fbuf_len * sizeof(float)); /* variables for reverb effect * delay_buffer is allocated in CCM.(64KB) * Maximum length Stereo 16bit(4bytes/sample) * 0.371s@44100Hz 0.341s@48000Hz */ delay_buffer_typedef delay_buffer; delay_buffer.ptr = (uint32_t*)CCM_BASE; delay_buffer.size = 65536 / sizeof(uint32_t); delay_buffer.idx = 0; IIR_Filter_Struct_Typedef IIR; IIR.delay_buffer = &delay_buffer; IIR.sbuf_size = dac_intr.bufferSize / 2; IIR.num_blocks = SoundDMAHalfBlocks; IIR.fs = wav.sampleRate; IIR.number = bass_boost_mode; boost = bass_boost_mode; IIR_Set_Params(&IIR); REVERB_Struct_Typedef RFX; RFX.delay_buffer = &delay_buffer; RFX.num_blocks = SoundDMAHalfBlocks; RFX.fs = wav.sampleRate; RFX.number = reverb_effect_mode; REVERB_Set_Prams(&RFX); FFT_Struct_Typedef FFT; FFT.ifftFlag = 0; FFT.bitReverseFlag = 1; FFT.length = 64; FFT.samples = dac_intr.bufferSize / ((wav.bitPerSample / 8) * wav.numChannel) / 2; if(wav.numChannel < 2){ FFT.samples >>= 1; }
static void file_rename_doc(const char *old_filename) { const char *ext=NULL; char *title=NULL; FILE *file; unsigned char buffer_header[512]; uint32_t *fat; const struct OLE_HDR *header=(const struct OLE_HDR*)&buffer_header; time_t file_time=0; unsigned int fat_entries; if(strstr(old_filename, ".sdd")!=NULL) ext="sdd"; if((file=fopen(old_filename, "rb"))==NULL) return; #ifdef DEBUG_OLE log_info("file_rename_doc(%s)\n", old_filename); #endif /*reads first sector including OLE header */ if(my_fseek(file, 0, SEEK_SET) < 0 || fread(&buffer_header, sizeof(buffer_header), 1, file) != 1) { fclose(file); return ; } /* Sanity check */ if(le32(header->num_FAT_blocks)==0 || le32(header->num_extra_FAT_blocks)>50 || le32(header->num_FAT_blocks)>109+le32(header->num_extra_FAT_blocks)*((1<<le16(header->uSectorShift))-1)) { fclose(file); return ; } if((fat=OLE_load_FAT(file, header))==NULL) { fclose(file); return ; } fat_entries=(le32(header->num_FAT_blocks)==0 ? 109: (le32(header->num_FAT_blocks)<<le16(header->uSectorShift))/4); { unsigned int ministream_block=0; unsigned int ministream_size=0; unsigned int block; unsigned int i; /* FFFFFFFE = ENDOFCHAIN * Use a loop count i to avoid endless loop */ #ifdef DEBUG_OLE log_info("file_rename_doc root_start_block=%u, fat_entries=%u\n", le32(header->root_start_block), fat_entries); #endif for(block=le32(header->root_start_block), i=0; block<fat_entries && block!=0xFFFFFFFE && i<fat_entries; block=le32(fat[block]), i++) { struct OLE_DIR *dir_entries; if(my_fseek(file, (1+block)<<le16(header->uSectorShift), SEEK_SET)<0) { free(fat); fclose(file); free(title); return ; } dir_entries=(struct OLE_DIR *)MALLOC(1<<le16(header->uSectorShift)); if(fread(dir_entries, 1<<le16(header->uSectorShift), 1, file)!=1) { free(fat); free(dir_entries); fclose(file); free(title); return ; } #ifdef DEBUG_OLE log_info("Root Directory block=%u (0x%x)\n", block, block); #endif { unsigned int sid; const struct OLE_DIR *dir_entry=dir_entries; if(i==0) { ministream_block=le32(dir_entry->start_block); ministream_size=le32(dir_entry->size); } for(sid=0, dir_entry=dir_entries; sid<(1<<le16(header->uSectorShift))/sizeof(struct OLE_DIR); sid++,dir_entry++) { if(dir_entry->type!=NO_ENTRY) { const char SummaryInformation[40]= { 0x05, '\0', 'S', '\0', 'u', '\0', 'm', '\0', 'm', '\0', 'a', '\0', 'r', '\0', 'y', '\0', 'I', '\0', 'n', '\0', 'f', '\0', 'o', '\0', 'r', '\0', 'm', '\0', 'a', '\0', 't', '\0', 'i', '\0', 'o', '\0', 'n', '\0', '\0', '\0' }; #ifdef DEBUG_OLE unsigned int j; for(j=0;j<64 && j<le16(dir_entry->namsiz) && dir_entry->name[j]!='\0';j+=2) { log_info("%c",dir_entry->name[j]); } log_info(" type %u", dir_entry->type); log_info(" Flags=%s", (dir_entry->bflags==0?"Red":"Black")); log_info(" sector %u (%u bytes)\n", (unsigned int)le32(dir_entry->start_block), (unsigned int)le32(dir_entry->size)); #endif switch(le16(dir_entry->namsiz)) { case 12: /* 3ds max */ if(memcmp(dir_entry->name, "S\0c\0e\0n\0e\0\0\0",12)==0) ext="max"; /* Licom AlphaCAM */ else if(memcmp(dir_entry->name,"L\0i\0c\0o\0m\0\0\0",12)==0) ext="amb"; break; case 16: if(sid==1 && memcmp(dir_entry->name, "d\0o\0c\0.\0d\0e\0t\0\0\0", 16)==0) ext="psmodel"; /* Windows Sticky Notes */ else if(sid==1 && memcmp(dir_entry->name, "V\0e\0r\0s\0i\0o\0n\0\0\0", 16)==0) ext="snt"; break; case 18: /* MS Excel * Note: Microsoft Works Spreadsheet contains the same signature */ if(ext==NULL && memcmp(dir_entry->name, "W\0o\0r\0k\0b\0o\0o\0k\0\0\0",18)==0) ext="xls"; /* Microsoft Works .wps */ else if(memcmp(dir_entry->name,"C\0O\0N\0T\0E\0N\0T\0S\0\0\0",18)==0) ext="wps"; break; case 20: /* Page Maker */ if(memcmp(&dir_entry->name, "P\0a\0g\0e\0M\0a\0k\0e\0r\0\0\0", 20)==0) ext="p65"; break; case 22: /* SigmaPlot .jnb */ if(memcmp(dir_entry->name, "J\0N\0B\0V\0e\0r\0s\0i\0o\0n\0\0", 22)==0) ext="jnb"; break; case 24: /* HP Photosmart Photo Printing Album */ if(memcmp(dir_entry->name,"I\0m\0a\0g\0e\0s\0S\0t\0o\0r\0e\0\0\0",24)==0) ext="albm"; break; case 28: /* Microsoft Works Spreadsheet or Chart */ if(memcmp(dir_entry->name,"W\0k\0s\0S\0S\0W\0o\0r\0k\0B\0o\0o\0k\0\0\0",28)==0) ext="xlr"; /* Visio */ else if(memcmp(dir_entry->name,"V\0i\0s\0i\0o\0D\0o\0c\0u\0m\0e\0n\0t\0\0\0",28)==0) ext="vsd"; /* SolidWorks */ else if(memcmp(&dir_entry->name, "s\0w\0X\0m\0l\0C\0o\0n\0t\0e\0n\0t\0s\0\0\0", 28)==0) { #ifdef DJGPP ext="sld"; #else ext="sldprt"; #endif } break; case 32: if(memcmp(dir_entry->name, "m\0a\0n\0i\0f\0e\0s\0t\0.\0c\0a\0m\0x\0m\0l\0\0\0",32)==0) ext="camrec"; break; case 34: if(memcmp(dir_entry->name, "S\0t\0a\0r\0C\0a\0l\0c\0D\0o\0c\0u\0m\0e\0n\0t\0\0\0",34)==0) ext="sdc"; break; case 36: /* sda=StarDraw, sdd=StarImpress */ if((ext==NULL || strcmp(ext,"sdd")!=0) && memcmp(dir_entry->name, "S\0t\0a\0r\0D\0r\0a\0w\0D\0o\0c\0u\0m\0e\0n\0t\0003\0\0\0", 36)==0) ext="sda"; else if(memcmp(dir_entry->name, "f\0i\0l\0e\0_\0C\0O\0M\0P\0A\0N\0Y\0_\0F\0I\0L\0E\0\0\0", 36)==0) ext="qbb"; break; case 38: /* Quattro Pro spreadsheet */ if(memcmp(dir_entry->name, "N\0a\0t\0i\0v\0e\0C\0o\0n\0t\0e\0n\0t\0_\0M\0A\0I\0N\0\0\0", 38)==0) ext="qpw"; else if(memcmp(dir_entry->name, "S\0t\0a\0r\0W\0r\0i\0t\0e\0r\0D\0o\0c\0u\0m\0e\0n\0t\0\0\0", 38)==0) ext="sdw"; break; case 40: if(memcmp(dir_entry->name, SummaryInformation, 40)==0) { OLE_parse_summary(file, fat, fat_entries, header, ministream_block, ministream_size, le32(dir_entry->start_block), le32(dir_entry->size), &ext, &title, &file_time); } else if(memcmp(dir_entry->name,"P\0o\0w\0e\0r\0P\0o\0i\0n\0t\0 \0D\0o\0c\0u\0m\0e\0n\0t\0\0\0", 40)==0) ext="ppt"; /* Outlook */ else if(memcmp(dir_entry->name,"_\0_\0n\0a\0m\0e\0i\0d\0_\0v\0e\0r\0s\0i\0o\0n\0001\0.\0000\0\0\0",40)==0) ext="msg"; break; case 46: if(memcmp(dir_entry->name, "I\0S\0o\0l\0i\0d\0W\0o\0r\0k\0s\0I\0n\0f\0o\0r\0m\0a\0t\0i\0o\0n\0\0\0", 46)==0) { #ifdef DJGPP ext="sld"; #else ext="sldprt"; #endif } break; case 56: /* Wilcom ES Software */ if(memcmp(dir_entry->name, WilcomDesignInformationDDD, 56)==0) ext="emb"; break; } if(sid==1 && le16(dir_entry->namsiz) >=6 && memcmp(dir_entry->name, "D\0g\0n", 6)==0) ext="dgn"; #ifdef DEBUG_OLE if(ext!=NULL) log_info("Found %s %u\n", ext, le16(dir_entry->namsiz)); #endif } } } free(dir_entries); } } free(fat); fclose(file); if(file_time!=0 && file_time!=(time_t)-1) set_date(old_filename, file_time, file_time); if(title!=NULL) { file_rename(old_filename, (const unsigned char*)title, strlen(title), 0, ext, 1); free(title); } else file_rename(old_filename, NULL, 0, 0, ext, 1); }
int PlaySound(int id) { int i, duration, curX, prevX, media_data_totalBytes; volatile int ret = RET_PLAY_NORM; uint32_t *dst32p; uint8_t *outbuf; char str[10]; WAVEFormatStruct wav; WAVEFormatHeaderStruct wavHeader; WAVEFormatChunkStruct wavChunk; MY_FILE *infile; char timeStr[20]; if(!(infile = my_fopen(id))){ ret = RET_PLAY_STOP; goto EXIT_WAV; } my_fread(&wavHeader, 1, sizeof(WAVEFormatHeaderStruct), infile); debug.printf("\r\n\n[WAVE]"); if(strncmp(wavHeader.headStrRIFF, "RIFF", 4) != 0){ debug.printf("\r\nNot contain RIFF chunk"); ret = RET_PLAY_STOP; goto EXIT_WAV; } debug.printf("\r\nFile Size:%d", wavHeader.fileSize); if(strncmp(wavHeader.headStrWAVE, "WAVE", 4) != 0){ debug.printf("\r\nThis is not WAVE file."); ret = RET_PLAY_STOP; goto EXIT_WAV; } int restBytes = wavHeader.fileSize; while(1){ // loop until format chunk is found my_fread(&wavChunk, 1, sizeof(WAVEFormatChunkStruct), infile); if(strncmp(wavChunk.chunkfmt, "fmt ", 4) == 0){ break; } memset(str, '\0', sizeof(str)); debug.printf("\r\n\nchunkType:%s", strncpy(str, wavChunk.chunkfmt, sizeof(wavChunk.chunkfmt))); debug.printf("\r\nchunkSize:%d", wavChunk.chunkSize); restBytes = restBytes - wavChunk.chunkSize - sizeof(WAVEFormatChunkStruct); if(restBytes <= 0){ debug.printf("\r\nNot Found Format Chunk."); ret = RET_PLAY_STOP; goto EXIT_WAV; } my_fseek(infile, wavChunk.chunkSize, SEEK_CUR); } my_fread(&wav, 1, sizeof(WAVEFormatStruct), infile); my_fseek(infile, wavChunk.chunkSize - sizeof(WAVEFormatStruct), SEEK_CUR); restBytes = restBytes - wavChunk.chunkSize - sizeof(WAVEFormatChunkStruct); while(1){ // loop until data chunk is found my_fread(&wavChunk, 1, sizeof(WAVEFormatChunkStruct), infile); if(strncmp(wavChunk.chunkfmt, "data", 4) == 0){ break; } memset(str, '\0', sizeof(str)); debug.printf("\r\n\nchunkType:%s", strncpy(str, wavChunk.chunkfmt, sizeof(wavChunk.chunkfmt))); debug.printf("\r\nchunkSize:%d", wavChunk.chunkSize); restBytes = restBytes - wavChunk.chunkSize - sizeof(WAVEFormatChunkStruct); if(restBytes <= 0){ debug.printf("\r\nNot Found Format Chunk."); ret = RET_PLAY_STOP; goto EXIT_WAV; } my_fseek(infile, wavChunk.chunkSize, SEEK_CUR); } memset(str, '\0', sizeof(str)); debug.printf("\r\n\nchunkType:%s", strncpy(str, wavChunk.chunkfmt, sizeof(wavChunk.chunkfmt))); debug.printf("\r\nchunkSize:%d", wavChunk.chunkSize); debug.printf("\r\n\nformatID:%d", wav.formatID); debug.printf("\r\nNum Channel:%d", wav.numChannel); debug.printf("\r\nSampling Rate:%d", wav.sampleRate); debug.printf("\r\nData Speed:%d", wav.dataSpeed); debug.printf("\r\nBlock Size:%d", wav.blockSize); debug.printf("\r\nBit Per Sample:%d", wav.bitPerSample); debug.printf("\r\nBytes Wave Data:%d", wavChunk.chunkSize); if(wav.formatID != 1){ debug.printf("\r\nthis media is not a PCM."); ret = RET_PLAY_STOP; goto EXIT_WAV; } int seekBytesSyncWord = infile->seekBytes; media_data_totalBytes = wavChunk.chunkSize; duration = wavChunk.chunkSize / wav.dataSpeed; setStrSec(timeStr, duration); debug.printf("\r\nplay time:%s", timeStr); LCDFadeIn(2, music_bgimg_160x128); memcpy((void*)frame_buffer, (void*)music_bgimg_160x128, sizeof(frame_buffer)); short xTag = 5, yTag = 50, disp_limit = 150, strLen; pcf_typedef pcf; pcf.dst_gram_addr = (uint32_t)frame_buffer; pcf.pixelFormat = PCF_PIXEL_FORMAT_RGB565; pcf.size = 16; pcf.color = WHITE; pcf.colorShadow = BLACK; pcf.alphaSoftBlending = 1; pcf.enableShadow = 1; pcf_font.metrics.hSpacing = 2; uint8_t strNameLFN[80]; if(setLFNname(strNameLFN, id, LFN_WITHOUT_EXTENSION, sizeof(strNameLFN))){ strLen = LCDGetStringLFNPixelLength(strNameLFN, pcf.size); if((xTag + strLen) < LCD_WIDTH){ disp_limit = LCD_WIDTH - 16; } else { disp_limit = LCD_WIDTH - 16; yTag -= 12; } LCD_GotoXY(xTag, yTag); LCDPutStringLFN(xTag, disp_limit - 1, 3, strNameLFN, &pcf); } else { char strNameSFN[9]; memset(strNameSFN, '\0', sizeof(strNameSFN)); setSFNname(strNameSFN, id); LCD_GotoXY(xTag, yTag); LCDPutString(strNameSFN, &pcf); } if(settings_group.music_conf.b.musicinfo && (wav.bitPerSample > 16) && (wav.sampleRate >= 48000)){ pcf.size = 12; pcf.color = RED; pcf.colorShadow = WHITE; LCD_GotoXY(5, 19); LCDPutString("Hi-Res ", &pcf); LCDPutString(wav.bitPerSample == 24 ? "24bit" : "32bit", &pcf); } pcf.size = 12; pcf.color = WHITE; pcf.colorShadow = GRAY; char s[30], s1[10]; SPRINTF(s, "%d/%d", id, fat.fileCnt - 1); LCD_GotoXY(5, MUSIC_INFO_POS_Y + 1); if(settings_group.music_conf.b.musicinfo){ strcat(s, " WAV "); SPRINTF(s1, "%.1fM ", (float)(wav.numChannel * wav.bitPerSample * wav.sampleRate) / 1000000.0f); strcat(s, s1); SPRINTF(s1, "%dkHz", (int)(wav.sampleRate / 1000)); strcat(s, s1); } LCDPutString(s, &pcf); uint16_t SOUND_BUFFER[12288]; uint8_t SOUND_BUFFER_24BIT[((sizeof(SOUND_BUFFER) / 2) / sizeof(uint32_t)) * 3]; dac_intr.fp = infile; dac_intr.buff = (uint8_t*)SOUND_BUFFER; if(wav.bitPerSample <= 16){ dac_intr.bufferSize = sizeof(SOUND_BUFFER) / 2; } else { dac_intr.bufferSize = sizeof(SOUND_BUFFER); } volatile int SoundDMAHalfBlocks = (dac_intr.bufferSize / (sizeof(int16_t) * 2)) / 2; FFT_Struct_Typedef FFT; FFT.bitPerSample = wav.bitPerSample; FFT.ifftFlag = 0; FFT.bitReverseFlag = 1; FFT.length = 16; FFT.samples = (dac_intr.bufferSize / (sizeof(int16_t) * wav.numChannel) / 2) / 1; if(wav.numChannel < 2){ FFT.samples >>= 1; }
/*pre:file is open * post: file pointer is set to start of file */ void my_rewind(t_my_file *fp){ my_fseek(fp, 0, SEEK_SET); }
int modify_defaults_file(const char *file_location, const char *option, const char *option_value, const char *section_name, int remove_option) { FILE *cnf_file; MY_STAT file_stat; char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer; size_t opt_len= 0, optval_len= 0, sect_len; uint nr_newlines= 0, buffer_size; my_bool in_section= FALSE, opt_applied= 0; uint reserve_extended; uint new_opt_len; int reserve_occupied= 0; DBUG_ENTER("modify_defaults_file"); if (!(cnf_file= my_fopen(file_location, O_RDWR | O_BINARY, MYF(0)))) DBUG_RETURN(2); /* my_fstat doesn't use the flag parameter */ if (my_fstat(fileno(cnf_file), &file_stat, MYF(0))) goto malloc_err; if (option && option_value) { opt_len= strlen(option); optval_len= strlen(option_value); } new_opt_len= opt_len + 1 + optval_len + NEWLINE_LEN; /* calculate the size of the buffer we need */ reserve_extended= (opt_len + 1 + /* For '=' char */ optval_len + /* Option value len */ NEWLINE_LEN + /* Space for newline */ RESERVE); /* Some additional space */ buffer_size= (file_stat.st_size + 1); /* The ending zero */ /* Reserve space to read the contents of the file and some more for the option we want to add. */ if (!(file_buffer= (char*) my_malloc(buffer_size + reserve_extended, MYF(MY_WME)))) goto malloc_err; sect_len= strlen(section_name); for (dst_ptr= file_buffer; fgets(linebuff, BUFF_SIZE, cnf_file); ) { /* Skip over whitespaces */ for (src_ptr= linebuff; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++) {} if (!*src_ptr) /* Empty line */ { nr_newlines++; continue; } /* correct the option (if requested) */ if (option && in_section && !strncmp(src_ptr, option, opt_len) && (*(src_ptr + opt_len) == '=' || my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) || *(src_ptr + opt_len) == '\0')) { char *old_src_ptr= src_ptr; src_ptr= strend(src_ptr+ opt_len); /* Find the end of the line */ /* could be negative */ reserve_occupied+= (int) new_opt_len - (int) (src_ptr - old_src_ptr); if (reserve_occupied >= (int) reserve_extended) { reserve_extended= (uint) reserve_occupied + RESERVE; if (!(file_buffer= (char*) my_realloc(file_buffer, buffer_size + reserve_extended, MYF(MY_WME|MY_FREE_ON_ERROR)))) goto malloc_err; } opt_applied= 1; dst_ptr= add_option(dst_ptr, option_value, option, remove_option); } else { /* If we are going to the new group and have an option to apply, do it now. If we are removing a single option or the whole section this will only trigger opt_applied flag. */ if (in_section && !opt_applied && *src_ptr == '[') { dst_ptr= add_option(dst_ptr, option_value, option, remove_option); opt_applied= 1; /* set the flag to do write() later */ reserve_occupied= new_opt_len+ opt_len + 1 + NEWLINE_LEN; } for (; nr_newlines; nr_newlines--) dst_ptr= strmov(dst_ptr, NEWLINE); /* Skip the section if MY_REMOVE_SECTION was given */ if (!in_section || remove_option != MY_REMOVE_SECTION) dst_ptr= strmov(dst_ptr, linebuff); } /* Look for a section */ if (*src_ptr == '[') { /* Copy the line to the buffer */ if (!strncmp(++src_ptr, section_name, sect_len)) { src_ptr+= sect_len; /* Skip over whitespaces. They are allowed after section name */ for (; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++) {} if (*src_ptr != ']') { in_section= FALSE; continue; /* Missing closing parenthesis. Assume this was no group */ } if (remove_option == MY_REMOVE_SECTION) dst_ptr= dst_ptr - strlen(linebuff); in_section= TRUE; } else in_section= FALSE; /* mark that this section is of no interest to us */ } } /* File ended. Apply an option or set opt_applied flag (in case of MY_REMOVE_SECTION) so that the changes are saved. Do not do anything if we are removing non-existent option. */ if (!opt_applied && in_section && (remove_option != MY_REMOVE_OPTION)) { /* New option still remains to apply at the end */ if (!remove_option && *(dst_ptr - 1) != '\n') dst_ptr= strmov(dst_ptr, NEWLINE); dst_ptr= add_option(dst_ptr, option_value, option, remove_option); opt_applied= 1; } for (; nr_newlines; nr_newlines--) dst_ptr= strmov(dst_ptr, NEWLINE); if (opt_applied) { /* Don't write the file if there are no changes to be made */ if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, MYF(MY_WME)) || my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer), MYF(MY_NABP))) goto err; } if (my_fclose(cnf_file, MYF(MY_WME))) DBUG_RETURN(1); my_free(file_buffer, MYF(0)); DBUG_RETURN(0); err: my_free(file_buffer, MYF(0)); malloc_err: my_fclose(cnf_file, MYF(0)); DBUG_RETURN(1); /* out of resources */ }