Line 1: |
Line 1: |
− | == pit.bin file reader ==
| |
| | | |
− | <source lang="c">
| |
− | /*
| |
− | * pitread.c -- pit.bin file reader by Ludo6431 <ludolacost_gm@il_com>
| |
− | */
| |
− |
| |
− | #include <stdlib.h>
| |
− | #include <stdio.h>
| |
− | #include <stdarg.h>
| |
− | #include <string.h>
| |
− | #include <time.h>
| |
− |
| |
− | typedef unsigned char u8;
| |
− | typedef unsigned short u16;
| |
− | typedef unsigned int u32;
| |
− | #ifndef BIT
| |
− | # define BIT(b) (1<<(b))
| |
− | #endif
| |
− |
| |
− | void mexit(int ret, char *format, ...) {
| |
− | if(format) {
| |
− | va_list ap;
| |
− | va_start(ap, format);
| |
− | vfprintf(stderr, format, ap);
| |
− | fprintf(stderr, "\n");
| |
− | va_end(ap);
| |
− | }
| |
− | exit(ret);
| |
− | }
| |
− |
| |
− | typedef struct PIT_HDR sPIT_HDR;
| |
− | struct PIT_HDR {
| |
− | u32 magic;
| |
− | u32 dunno1; // "00_1"
| |
− | u16 slotsnum; // 3000 slots in the file
| |
− | u16 msbfolderctr;
| |
− | u16 lsbfolderctr; // next folder's number will be ++folderctr
| |
− | u16 photoctr; // next photo's number will be ++photoctr
| |
− | u16 dunno2; // 0x0000
| |
− | u16 framectr; // next frame's number will be ++framectr
| |
− | u16 checksum; // crc16 of whole file
| |
− | u16 hdrsize; // 0x18
| |
− | };
| |
− |
| |
− | #define F_DIRNUM(f) (((f)&0x1)*100 + ((f)>>1)&0x7f) // 8bits (100-129)
| |
− | #define F_ENTNUM(f) ((((f)>>11)&0x7f)+1) // 7bits (0-99)
| |
− | #define F_STICKER(f) (((f)>>18)&0x3)
| |
− | #define F_TYPE(f) (((f)>>20)&0x1)
| |
− | typedef struct PIT_ENTRY sPIT_ENTRY;
| |
− | struct PIT_ENTRY {
| |
− | u32 date;
| |
− | u8 dunno[8];
| |
− | u32 flags; // (bit0: hundreds' digit of folder num; bit1-7: tens' digits of folder num; bit8-10: UNKNOWN (0); bit11-17: photo's number minus 1; bit18-19: sticker 0: None, 1: Star, 2: Clover, 3: Heart; bit20: type 0:photo, 1:frame; bit21-31: UNKNOWN (0))
| |
− | };
| |
− |
| |
− | int main(int argc, char *argv[]) {
| |
− | if(argc!=2) mexit(1, "Usage:\n\t%s <pit.bin>", argv[0]);
| |
− |
| |
− | char *fname = argv[1];
| |
− | FILE *fd = fopen(fname, "rb+");
| |
− | if(!fd) mexit(1, "Can't open file \"%s\"!", fname);
| |
− |
| |
− | fseek(fd, 0, SEEK_END);
| |
− | unsigned fsize = ftell(fd);
| |
− | rewind(fd);
| |
− |
| |
− | sPIT_HDR hdr;
| |
− |
| |
− | if(fread((void *)&hdr, 1, sizeof(sPIT_HDR), fd)!=sizeof(sPIT_HDR)) {
| |
− | fclose(fd);
| |
− | mexit(1, "Can't read file \"%s\"!", fname);
| |
− | }
| |
− |
| |
− | printf("magic : \"%c%c%c%c\"\n", hdr.magic>>24, (hdr.magic>>16)&0xFF, (hdr.magic>>8)&0xFF, hdr.magic&0xFF);
| |
− | printf("dunno1 : \"%c%c%c%c\"\n", hdr.dunno1&0xFF, (hdr.dunno1>>8)&0xFF, (hdr.dunno1>>16)&0xFF, hdr.dunno1>>24);
| |
− | printf("slotsnum : %d\n", hdr.slotsnum);
| |
− | printf("folderctr : %d%02d\n", hdr.msbfolderctr, hdr.lsbfolderctr);
| |
− | printf("photoctr : %d\n", hdr.photoctr);
| |
− | printf("framectr : %d\n", hdr.framectr);
| |
− | printf("checksum : 0x%02x\n", hdr.checksum);
| |
− | printf("headersize : %d\n", hdr.hdrsize);
| |
− |
| |
− | // jump after the header
| |
− | fseek(fd, hdr.hdrsize, SEEK_SET);
| |
− |
| |
− | u32 i, photocnt=0, framecnt=0, offset;
| |
− | sPIT_ENTRY entry;
| |
− | for(i=0; i<hdr.slotsnum; i++) {
| |
− | offset = ftell(fd);
| |
− | if(fread((void *)&entry, 1, sizeof(sPIT_ENTRY), fd)!=sizeof(sPIT_ENTRY)) {
| |
− | fclose(fd);
| |
− | mexit(1, "Can't read file \"%s\" (after %d+%d valid entries)!", fname, photocnt, framecnt);
| |
− | }
| |
− |
| |
− | if(!entry.date) continue;
| |
− |
| |
− | switch(F_TYPE(entry.flags)) {
| |
− | case 0: // photo
| |
− | photocnt++;
| |
− | printf("-- photo%04d -- (slot%d in file)\n", photocnt, (offset-hdr.hdrsize)>>4);
| |
− | break;
| |
− | case 1: // frame
| |
− | framecnt++;
| |
− | printf("-- frame%04d -- (slot%d in file)\n", framecnt, (offset-hdr.hdrsize)>>4);
| |
− | break;
| |
− | default:
| |
− | break;
| |
− | }
| |
− |
| |
− | struct tm ttm;
| |
− | time_t stm;
| |
− | bzero(&ttm, sizeof(ttm));
| |
− | ttm.tm_year = 2000 - 1900; // 2000
| |
− | ttm.tm_mon = 0; // january
| |
− | ttm.tm_mday = 1; // 1st
| |
− | stm = mktime(&ttm);
| |
− | stm += entry.date;
| |
− |
| |
− | printf(" date(UTC) : %s", asctime(gmtime(&stm)));
| |
− | printf(" folder : %d\n", F_DIRNUM(entry.flags));
| |
− | printf(" number : %d\n", F_ENTNUM(entry.flags));
| |
− |
| |
− | char fname[128];
| |
− | switch(F_TYPE(entry.flags)) {
| |
− | case 0:
| |
− | printf(" sticker : %d\n", F_STICKER(entry.flags));
| |
− | sprintf(fname, "/DCIM/%03dNIN02/HNI_%04d.JPG", F_DIRNUM(entry.flags), F_ENTNUM(entry.flags));
| |
− | break;
| |
− | case 1:
| |
− | sprintf(fname, "/private/ds/app/484E494A/DCIM/%03dNIN02/HNI_%04d.JPG", F_DIRNUM(entry.flags), F_ENTNUM(entry.flags));
| |
− | break;
| |
− | default:
| |
− | break;
| |
− | }
| |
− |
| |
− | printf(" filename : %s\n", fname);
| |
− | }
| |
− | printf("The file contains %d photos and %d frames.\n", photocnt, framecnt);
| |
− |
| |
− | fclose(fd);
| |
− | }
| |
− | </source>
| |