Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ppm_expander.cpp

Go to the documentation of this file.
00001 /*
00002  * Interface pour le programme de compression
00003  * (c) 1995 Fabrice Bellard
00004  */
00005 
00006 #include <stdlib.h>
00007 //#include <unistd.h>
00008 #include <stdio.h>
00009 #include <string.h>
00010 #include <time.h>
00011 
00012 /***************************************************************************
00013  * Interface avec les routines de compression
00014  */
00015 
00016 #define METHOD_NB      2   /* nombre total de méthodes de compression */
00017 
00018 #define METHOD_STORE   0
00019 #define METHOD_PPM     1
00020 
00021 
00022 #define DEFAULT_SUFFIX  ".st"    /* extension par défault */
00023 /* signature en début de fichier */
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   //fprintf(stderr,"<%u,%u,%u>\n",maxnode,blocksize,numblocks);
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

Generated on Sat Nov 5 16:16:56 2005 for OPIE by  doxygen 1.4.2