/* * one.c -- ONE archive handler * (C)Copyright 2000 by TAJIRI Yasuhiro * This file is part of Enfle. * * Last Modified: Sat Oct 7 12:20:24 2000. * $Id: one.c,v 1.3 2000/10/07 16:28:18 sian Exp $ * * Enfle is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Enfle is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * 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 */ #include #include "enfle.h" #include "mfile.h" #include "one.h" #include "utils.h" #include "plugin.h" static void decode(char *dst,const char* src,int fsize,int offset,int size); int one_archive_bmp_seek(Archive *ar, long offset, int whence); int one_archive_bmp_tell(Archive *ar); #undef DEBUG int #ifdef PIC get_plugininfo(PluginInfo *p) #else archiver_one_get_plugininfo(PluginInfo *p) #endif { p->version = 1; p->type = _Archiver; p->pluginname = "One Format Archiver Plugin version 0.4"; p->pluginshortname = FORMAT_NAME; p->author = "TAJIRI Yasuhiro"; p->dlhandle = NULL; /* set by plugin_load */ p->functions.archiver.open = one_archive_open; return 1; } int one_archive_open(Archive *ar) { ONE_info *info; ONE_info_table* table; int FileCount; unsigned char buf[10]; int i; #ifdef DEBUG fprintf(stderr, "one_archive_open: open %s\n", ar->filename); #endif if ((ar->fp = fopen(ar->filename, "rb")) == NULL) return 0; fseek(ar->fp, 0L, SEEK_END); ar->asize = ftell(ar->fp); fseek(ar->fp, 0L, SEEK_SET); if (fread(buf, 1, 10, ar->fp) != 10) { fclose(ar->fp); return 0; } if (memcmp(buf,"YS ver1.00", 10) != 0) { fclose(ar->fp); return 0; } #ifdef DEBUG fprintf(stderr, "one_archive_open: open %sOK\n", ar->filename); #endif /* allocate plugin unique info */ if ((ar->info = calloc(1, sizeof(ONE_info))) == NULL) { fprintf(stderr, "one_archive_open: No enough memory for info\n"); return 0; } info = (ONE_info *)ar->info; fread(&FileCount,sizeof(int),1,ar->fp); /* archieveに含まれるファイル数:BIG Endianでも使えるようにする */ ar->nfiles =get_little_dword(&FileCount); if((table = (ONE_info_table*) malloc(sizeof(ONE_info_table)*ar->nfiles)) ==NULL){ fprintf(stderr, "one_archive_open: No enough memory for info\n"); free(ar->info); return 0; } fread(table,sizeof(ONE_info_table),ar->nfiles,ar->fp); /* BIG ENDIANの判定(手抜き)ONEならこれでいい */ if(ar->nfiles != FileCount){ for(i=0;infiles;i++){ table[i].offsets=get_little_dword(&(table[i].offsets)); table[i].sizes=get_little_dword(&(table[i].sizes)); } } fread(buf,sizeof(char),sizeof(buf),ar->fp); fseek(ar->fp, (table[0]).offsets, SEEK_SET); if (memcmp(buf,"BM", 2) == 0) { info->type=BMP; ar->seek = one_archive_bmp_seek; ar->tell = one_archive_bmp_tell; } else { info->type=JPEG; ar->seek = NULL; ar->tell = NULL; } info->bmp_file=NULL; info->table = table; ar->format = FORMAT_NAME; ar->select =one_archive_select; ar->read = one_archive_read; ar->close = one_archive_close; return 1; } int one_archive_close(Archive *ar) { int f = fclose(ar->fp); ONE_info* info = (ONE_info *)ar->info; free(info->table); free(ar->info); return f; } static int one_archive_bmp_select(Archive* ar) { ONE_info *info = ar->info; FILE* fp = ar->fp; MFILE* out=info->bmp_file; unsigned char* file_buf; unsigned char *p; int i=ar->size; int c; file_buf = p = malloc(ar->size); if(p==NULL)return 0; if(fread(file_buf,1,ar->size,fp)!=ar->size){ free(p); return 0; } info->type=BMP; out = mopen(30000000); p=file_buf; while(i--){ c = *p; p++; if (c == 0xF0) { // F0 が現われて、 c=*p; p++; i--; switch(c){ case 0: break; case 1: mputc(0xf0,out); break; case 2: mputcn(0xf0,out,2); break; default: mputcn(*p,out,c); p++;i--; } } else{ mputc(c,out); } } mseek(out,0,SEEK_SET); info->bmp_file=out; return 1; } int one_archive_select(Archive *ar, int index) { ONE_info *info = ar->info; char buf[2]; if (index < 0) return 0; sprintf(ar->ifname, "%d",index); if(info->bmp_file){ // fclose(info->bmp_file); mclose(info->bmp_file); info->bmp_file=NULL; } ar->offset = ((info->table)[index]).offsets; ar->size = ((info->table)[index]).sizes; fseek(ar->fp, ar->offset, SEEK_SET); fread(buf,sizeof(char),sizeof(buf),ar->fp); fseek(ar->fp, ar->offset, SEEK_SET); if (memcmp(buf,"BM", 2) == 0) { ar->seek = one_archive_bmp_seek; ar->tell = one_archive_bmp_tell; return one_archive_bmp_select(ar); } else { ar->seek = NULL; ar->tell = NULL; info->type=JPEG; } return 1; } int one_archive_bmp_seek(Archive *ar, long offset, int whence) { ONE_info *info = ar->info; return mseek(info->bmp_file, offset, whence); } int one_archive_bmp_tell(Archive *ar) { ONE_info *info = ar->info; return mtell(info->bmp_file); } static int one_archive_bmp_read(Archive *ar, unsigned char *buf, int size) { ONE_info *info = ar->info; return mread(buf,1,size,info->bmp_file); } int one_archive_read(Archive *ar, unsigned char *buf, int size) { int s; ONE_info *info = (ONE_info*)(ar->info); if(info->type==JPEG){ int k = (ftell(ar->fp) - ar->offset); if ((s = fread(buf, 1, size, ar->fp)) == 0) return 0; decode(buf,buf,ar->size,k,size); } else if (info->type==BMP){ int i =one_archive_bmp_read(ar, buf, size); return i; } else { return 0; } return s; } static void decode(char *dst,const char* src,int fsize,int offset,int size) { char key[] = "YET11.ITaRu.MiKiPoN.ShiNoRi-"; //暗号・復号キー int bufsize = 0x1000; int l = strlen(key); int num = fsize / bufsize; int i,j; for(i=(offset%bufsize);i