home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / disk / misc / TransADF.lha / TransADF / Source / defl_disk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-05  |  7.8 KB  |  245 lines

  1. /* defl_disk.c - Delfate a disk into a compressed file
  2. ** Copyright (C) 1997,1998 Karl J. Ots
  3. ** 
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU General Public License as published by
  6. ** the Free Software Foundation; either version 2 of the License, or
  7. ** (at your option) any later version.
  8. ** 
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU General Public License for more details.
  13. ** 
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. */
  18.  
  19. #include <exec/types.h>
  20. #include <exec/memory.h>
  21. #include <devices/trackdisk.h>
  22. #include <dos/dos.h>
  23. #include <clib/exec_protos.h>
  24. #include <clib/dos_protos.h>
  25.  
  26. #include "zlib.h"
  27.  
  28. #include "defl_disk.h"
  29. #include "main.h"
  30. #include "mem_chunks.h"
  31. #include "device.h"
  32. #include "util.h"
  33. #include "errors.h"
  34.  
  35.  
  36. #define DD_TBTRACKS 1                           /* Tracks in dd_TrackBuf */
  37. #define DD_TBSIZE   (DD_TBTRACKS * trackSize)   /* Bytes in dd_TrackBuf  */
  38. #define DD_FBSIZE   (32*1024)                   /* Bytes in dd_FileBuf   */
  39.  
  40. UBYTE *dd_TrackBuf;    /* Our input buffer - reads from disk. */
  41. UBYTE *dd_FileBuf;     /* Our output buffer - writes to file. */
  42.  
  43.  
  44. /*
  45. ** Deflate a disk into a file.
  46. ** Expects all fields of adfPkt to be set.
  47. */
  48. void deflDisk (struct ADF_Packet *adfPkt, ULONG deflLevel, STRPTR origName,
  49.                ULONG fileType)
  50. {
  51.   static z_stream defl_stream;
  52.   ULONG nextTrack, CRC, USize, CSize;
  53.   LONG DOSError;
  54.   BYTE IOError;
  55.   int zerr, ocnt, deflg, winbits;
  56.   
  57.   
  58.   /* Output info header */
  59.   FPrintf (StdOut, "Deflating from %s unit %ld (%s:) to %s.\n",
  60.                    adfPkt->devInfo->deviceName,
  61.                    adfPkt->devInfo->deviceUnit,
  62.                    adfPkt->devInfo->dosName,
  63.                    adfPkt->ADFileName);
  64.   
  65.   FPrintf (StdOut, "Starting at track %ld, Ending at track %ld.\n",
  66.                    (adfPkt->startTrack/adfPkt->devInfo->numHeads),
  67.                    (adfPkt->endTrack/adfPkt->devInfo->numHeads));
  68.   
  69.   FPuts (StdOut, "Compressing disk as a ");
  70.   switch (fileType) {
  71.   case FT_ZLIB:      FPuts (StdOut, "ZLib");  break;
  72.   case FT_GZIP:      FPuts (StdOut, "GZip");  break;
  73.   case FT_PKZIP:     
  74.   case FT_PKZIP_ADD: FPuts (StdOut, "PKZip"); break;
  75.   }
  76.   FPuts (StdOut, " file.\n");
  77.   
  78.   
  79.   /* Allocate the buffers */
  80.   dd_TrackBuf = (UBYTE *)myAllocMem (DD_TBSIZE, MEMF_CLEAR);
  81.   dd_FileBuf  = (UBYTE *)myAllocMem (DD_FBSIZE, MEMF_CLEAR);
  82.   if (!dd_TrackBuf || !dd_FileBuf)
  83.   {
  84.     /* No Memory */
  85.     FPrintf (StdErr, "%s: Out of memory.\n", ProgName);
  86.     cleanExit(RETURN_FAIL, ERROR_NO_FREE_STORE);
  87.   }
  88.   
  89.   /* Output the file header */
  90.   if (writeHead (adfPkt->ADFile, origName, fileType) == FALSE)
  91.   {
  92.     DOSError = IoErr();
  93.     
  94.     FPrintf (StdErr, "%s: Error - Couldn't write file header.\n",ProgName);
  95.     
  96.     if (DOSError)
  97.       reportDOSError(DOSError);
  98.     
  99.     cleanExit (RETURN_FAIL, NULL);
  100.   }
  101.   
  102.   /* Initialise the z_stream */
  103.   if (fileType == FT_ZLIB) winbits = 15;
  104.   else winbits = -15; /* windowBits is passed < 0 to suppress zlib header */    
  105.   defl_stream.zalloc = Z_NULL;
  106.   defl_stream.zfree  = Z_NULL;
  107.   defl_stream.opaque = Z_NULL;
  108.   zerr = deflateInit2 (&defl_stream, deflLevel,
  109.                        Z_DEFLATED, winbits, 8, 0);
  110.   if (zerr != Z_OK)
  111.   {
  112.     FPrintf (StdErr, "%s: Deflate Init Error - ", ProgName);
  113.     reportZLibError (zerr);
  114.     if (defl_stream.msg) FPrintf (StdErr, "\t(%s)\n", defl_stream.msg);
  115.     cleanExit (RETURN_FAIL, NULL);
  116.   }
  117.     
  118.   /* Start deflateing */
  119.   defl_stream.avail_in  = 0;           /* Input buffer is empty    */
  120.   defl_stream.next_out  = dd_FileBuf;  /* Pointer to output buffer */
  121.   defl_stream.avail_out = DD_FBSIZE;   /* output buffer is empty   */
  122.   deflg = Z_NO_FLUSH;
  123.   CRC = crc32 (NULL, Z_NULL, 0);       /* Initialise the CRC       */
  124.   nextTrack = adfPkt->startTrack;
  125.   while (1)
  126.   {
  127.     if (defl_stream.avail_in == 0)  /* Input is empty */
  128.       if (nextTrack <= adfPkt->endTrack)
  129.       {
  130.         /* Update progress report */
  131.         FPrintf (StdOut, "\rReading   track %ld side %ld",
  132.                          (nextTrack/adfPkt->devInfo->numHeads),
  133.                          (nextTrack%adfPkt->devInfo->numHeads));
  134.         Flush (StdOut);
  135.         
  136.         /* Fill the input buffer from disk */
  137.         IOError = readTrack (dd_TrackBuf, DD_TBTRACKS, nextTrack, 
  138.                              adfPkt->diskReq);
  139.         if (IOError)
  140.         {
  141.           FPutC (StdOut, '\n');
  142.           FPrintf (StdErr, "%s: Error reading from %s: - ",
  143.                            ProgName, adfPkt->devInfo->dosName);
  144.           reportIOError (IOError);
  145.           deflateEnd (&defl_stream);
  146.           cleanExit (RETURN_FAIL, NULL);
  147.         }
  148.         
  149.         nextTrack++;
  150.         defl_stream.next_in  = dd_TrackBuf;
  151.         defl_stream.avail_in = DD_TBSIZE;
  152.       }
  153.     
  154.     if (defl_stream.avail_in == 0)  /* Still zero - no more input */
  155.       deflg = Z_FINISH;
  156.     else
  157.       /* New data - Update the CRC */
  158.       CRC = crc32 (CRC, dd_TrackBuf ,defl_stream.avail_in);
  159.     
  160.     /* Fill the output buffer with deflated data, and keep filling */
  161.     /* it until no more inflated data exists in the input buffer.  */
  162.     while (1)
  163.     {
  164.       /* Check for Control-C break */
  165.       if (CTRL_C)
  166.       {
  167.         FPutC (StdOut, '\n');
  168.         FPrintf (StdErr, "%s - %s\n", breakText, ProgName);
  169.         deflateEnd (&defl_stream);
  170.         cleanExit (RETURN_WARN, NULL);
  171.       }
  172.       
  173.       /* Upate progress report */
  174.       FPuts (StdOut, "\rDeflating ");
  175.       Flush (StdOut);
  176.       
  177.       zerr = deflate (&defl_stream, deflg);
  178.       if (zerr < Z_OK)
  179.       {
  180.         FPutC (StdOut, '\n');
  181.         FPrintf (StdErr, "%s: Deflate error - ", ProgName);
  182.         reportZLibError (zerr);
  183.         if (defl_stream.msg) FPrintf (StdErr, "\t%s\n", defl_stream.msg);
  184.         deflateEnd (&defl_stream);
  185.         cleanExit (RETURN_FAIL, NULL);
  186.       }
  187.       
  188.       /* Flush the output buffer */
  189.       ocnt = DD_FBSIZE - defl_stream.avail_out;
  190.       if (ocnt) 
  191.       {
  192.         if ( Write (adfPkt->ADFile, dd_FileBuf, ocnt) != ocnt)
  193.         {
  194.           DOSError = IoErr();
  195.           
  196.           FPutC (StdOut, '\n');
  197.           FPrintf (StdErr, "%s: Error writing deflated data - ", ProgName);
  198.           reportDOSError(DOSError);
  199.           
  200.           cleanExit (RETURN_FAIL, DOSError);
  201.         }
  202.       }
  203.       defl_stream.next_out  = dd_FileBuf;
  204.       defl_stream.avail_out = DD_FBSIZE;
  205.       
  206.       if ((ocnt != DD_FBSIZE) || (zerr == Z_STREAM_END))
  207.         /* Last deflate() did not completely fill the output buffer,  */
  208.         /* thus no more data is pending, or we reached the end of the */
  209.         /* compressed data stream.                                    */
  210.         break;
  211.     }
  212.     if (zerr == Z_STREAM_END) break;
  213.   }
  214.   USize = defl_stream.total_in;
  215.   CSize = defl_stream.total_out;
  216.   
  217.   FPrintf (StdOut, "\rDeflated: %ld ==> %ld (%ld%%).   ",
  218.                    USize, CSize, ((CSize * 100) / USize));
  219.   Flush (StdOut);
  220.   
  221.   /* End the deflate process */
  222.   zerr = deflateEnd (&defl_stream);
  223.   if (zerr != Z_OK)
  224.   {
  225.     FPutC (StdOut, '\n');
  226.     FPrintf (StdErr, "%s: Deflate End Error - ", ProgName);
  227.     reportZLibError (zerr);
  228.     if (defl_stream.msg) FPrintf (StdErr, "\t(%s)\n", defl_stream.msg);
  229.     cleanExit (RETURN_FAIL, NULL);
  230.   }
  231.   
  232.   /* Finish the file */
  233.   if ( finishFile (adfPkt->ADFile, CRC, CSize, USize, fileType) == FALSE)
  234.   {
  235.     FPutC (StdOut, '\n');
  236.     FPrintf (StdErr, "%s: Error - Couldn't finish output file correctly.\n",
  237.                      ProgName);
  238.     cleanExit (RETURN_FAIL, NULL);
  239.   }
  240.   
  241.   /* Free and clear buffers */
  242.   myFreeMem (dd_TrackBuf);
  243.   myFreeMem (dd_FileBuf);
  244. }
  245.