00001
00002
00003
00004
00005
00006 #include <stdlib.h>
00007
00008 #include <stdio.h>
00009 #include <string.h>
00010 #include <time.h>
00011
00012
00013
00014
00015
00016 #define METHOD_NB 2
00017
00018 #define METHOD_STORE 0
00019 #define METHOD_PPM 1
00020
00021
00022 #define DEFAULT_SUFFIX ".st"
00023
00024 #define STAT_MAGIC_SIZE 4
00025 char stat_magic[STAT_MAGIC_SIZE]={'P','P','M','S'};
00026
00027 #include "ppm_expander.h"
00028
00029 ppm_expander::~ppm_expander() {
00030 if (needppmend) ppm.PPM_End();
00031 ppm.arith.Arith_DecodeEnd();
00032 if (buf_in!=NULL) delete [] buf_in;
00033 if (buf_out!=NULL) delete [] buf_out;
00034 if (my_read_buf != NULL) delete my_read_buf;
00035 if (my_file_in != NULL) fclose(my_file_in);
00036 }
00037
00038 int ppm_expander::OpenFile(const char* infile)
00039 {
00040 my_file_in=fopen(infile,"rb");
00041 my_read_buf = new PPM_ReadBuf(my_file_in, this);
00042 return home();
00043 }
00044
00045 void ppm_expander::sizes(unsigned long& file, unsigned long& text)
00046 {
00047 struct stat _stat;
00048 fstat(fileno(my_file_in),&_stat);
00049 file = _stat.st_size;
00050 text = numblocks*blocksize;
00051 }
00052
00053 int ppm_expander::home()
00054 {
00055 fseek(my_file_in,0, SEEK_SET);
00056 unsigned char header[STAT_MAGIC_SIZE];
00057 size_t len=fread(header,1,STAT_MAGIC_SIZE,my_file_in);
00058 if (strncmp((char*)header,stat_magic,STAT_MAGIC_SIZE)!=0) {
00059 return 1;
00060 }
00061 if (len!=(STAT_MAGIC_SIZE)) {
00062 return 1;
00063 }
00064 if (fread(&maxnode,sizeof(maxnode),1,my_file_in) != 1) return 1;
00065 if (fread(&blocksize,sizeof(blocksize),1,my_file_in) != 1) return 1;
00066 if (fread(&numblocks,sizeof(numblocks),1,my_file_in) != 1) return 1;
00067
00068 locate(0,0);
00069 outbytes = 0;
00070 return 0;
00071 }
00072
00073 void ppm_expander::locate(unsigned int n) {
00074 locate(n/blocksize, n%blocksize);
00075 outbytes = n;
00076 }
00077
00078 void ppm_expander::locate(unsigned short block, unsigned int n)
00079 {
00080 if (needppmend)
00081 {
00082 ppm.PPM_End();
00083 needppmend = false;
00084 }
00085 size_t fpos;
00086 fseek(my_file_in,STAT_MAGIC_SIZE+sizeof(maxnode)+sizeof(blocksize)+sizeof(numblocks)+block*sizeof(fpos),SEEK_SET);
00087 fread(&fpos,sizeof(fpos),1,my_file_in);
00088 fseek(my_file_in,fpos,SEEK_SET);
00089
00090 ppm.arith.Arith_DecodeInit(my_read_buf,buf_in,bufsize);
00091 int err=ppm.PPM_Init(maxnode);
00092 needppmend = true;
00093 curblock = block;
00094 for (int i = 0; i < n; i++) getch();
00095 }
00096
00097 int ppm_expander::getch() {
00098 if (curblock >= numblocks) return EOF;
00099 int c=ppm.PPM_Decode();
00100 if (c == SYM_EOF)
00101 {
00102 if (++curblock >= numblocks) return EOF;
00103 locate(curblock,0);
00104 c = ppm.PPM_Decode();
00105 }
00106 outbytes++;
00107 return (c==SYM_EOF) ? EOF : c;
00108 }
00109
00110 UINT PPM_ReadBuf::readbuf(UCHAR *buf,UINT len)
00111 {
00112 UINT len1;
00113 parent->unsuspend();
00114 len1=fread(buf,1,len,my_file_in);
00115 return len1;
00116 }
00117
00118
00119 #ifndef __STATIC
00120 extern "C"
00121 {
00122 CExpander* newcodec() { return new ppm_expander; }
00123 }
00124 #endif