home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / D64ZIP.LHA / D64-Zipcode / Source / d64zipcode.c next >
Encoding:
C/C++ Source or Header  |  1996-01-23  |  4.8 KB  |  211 lines

  1.  
  2. static char info[]=" D64 2 Zipcode   Version 1.0   Tony Ambardar (C) 1993\n";
  3. /*
  4. Wrote this mostly by looking through some zipcode 4-packs and playing with
  5. Zipcode 2.0, so that I could try .D64 software from the watson archive on
  6. my C64 at home. No guarantees.
  7.  
  8. You are free to re-use this code so long as you give credit where it's due.
  9.  
  10. (C) 1993     Tony Ambardar
  11. */
  12.  
  13. #include <stdio.h>
  14. #include <errno.h>
  15. #include <string.h>
  16.  
  17. #define DBLOCKS (683)
  18.  
  19. typedef unsigned char byte;
  20. typedef enum { WHOLE=0, VARIABLE, NONE } repeat_t;
  21. static char repeat_c[]=".oO";
  22.  
  23. byte image_buffer[DBLOCKS*256],max_sector[35];
  24. static byte trk_lims[4] = {0, 8, 16, 25};
  25.  
  26. /* Per sector info */
  27.  
  28. int num_repeats;
  29. byte repchar;
  30. int rle_len;
  31. struct 
  32. {
  33.   int startpos;
  34.   int len;
  35. } rep_info[64];
  36.  
  37. static char filename[255] = "0!";
  38.  
  39. FILE *imgfile,*zipfile;
  40.  
  41. main(int argc, char *argv[]) 
  42. {
  43.   repeat_t rep_scan();
  44.   byte *sec_buf;
  45.   int i,j,k,track, sector,base;
  46.   int oddadd,evenadd,begin,length;
  47.   int pos;
  48.    
  49.   repeat_t sec_type;
  50.    
  51.   if(argc != 2) {
  52.     printf("%s",info);
  53.     printf("Converts a .D64 disk image to a Zipcode 4-pack\n\n");      
  54.     printf("Usage: %s  diskimage.d64\n",argv[0]);
  55.     exit(0);
  56.   }
  57.  
  58.   init_stuff(argv[1]);
  59.  
  60.   if ((pos = strcspn(argv[1], ".d64")) == 0)
  61.     pos = strcspn(argv[1], ".D64");
  62.  
  63.   argv[1][pos] = 0;
  64.  
  65.   zipfile = NULL;
  66.   strcat(filename,argv[1]);
  67.   printf("%s\n", filename);
  68.   base=0;
  69.   oddadd=11, evenadd= -10;
  70.   printf("\n            RLE Compression Map:\n");
  71.   printf("O = No Compression  -->  . = Max. Compression\n");
  72.   for(track=0; track<35; base+=max_sector[track++]+1) {
  73.     printf("\nTrack: %2u ",track+1);
  74.     openfiles(track,filename);
  75.     if(track==17 || track==24) --oddadd, ++evenadd;
  76.     i=base-evenadd;
  77.     sector= -evenadd;
  78.     for(k=0; k <= max_sector[track]; k++) {
  79.       i+= k % 2 ? oddadd : evenadd;
  80.       sec_buf = image_buffer +i*256;
  81.       sector += k % 2 ? oddadd : evenadd;
  82.       sec_type = rep_scan(sec_buf);
  83.       printf("%c",repeat_c[sec_type]);
  84.  
  85. #ifdef EBUG1
  86.       printf("\nT: %2u S: %2u Type: %c  Repchar: %3u\n",track+1,sector,
  87.          repeat_c[sec_type],repchar);
  88. #endif
  89.  
  90. #ifdef EBUG2
  91.       for(j=0;j<256;j++)
  92.     printf("\\%3o",*(sec_buf+j));
  93. #endif   
  94.  
  95.       if(sec_type==NONE) {
  96.     fputc(track+1,zipfile),fputc(sector,zipfile);
  97.     fwrite((sec_buf),1,256,zipfile);
  98.       }
  99.       else if(sec_type==WHOLE) {
  100.     fputc(track+1+64,zipfile),fputc(sector,zipfile);
  101.     fputc(*(sec_buf),zipfile);
  102.       }
  103.       else {            /* VARIABLE */
  104.     fputc(track+1+128,zipfile),fputc(sector,zipfile);
  105.     fputc(rle_len,zipfile),fputc(repchar,zipfile);
  106.     for(j=0; j<num_repeats; j++) {
  107.       begin= j==0? 0 : 
  108.       rep_info[j-1].startpos+rep_info[j-1].len;
  109.       length = rep_info[j].startpos - begin;
  110.       fwrite((sec_buf+begin),1,length,zipfile);
  111.       fputc(repchar,zipfile),
  112.       fputc(rep_info[j].len,zipfile);
  113.       fputc(*(sec_buf+rep_info[j].startpos),zipfile);
  114.     }
  115.     begin=rep_info[j-1].startpos+rep_info[j-1].len;
  116.     length = 256 - begin;
  117.     fwrite((sec_buf+begin),1,length,zipfile);
  118.       }
  119.     }
  120.   }
  121.   printf("\n\nDone.\n");
  122.   close(zipfile);
  123. }
  124.  
  125. openfiles(int trk,char *name)
  126. {
  127.   int i;
  128.   for(i=0; i<4; i++)
  129.     if(trk_lims[i] == trk) {
  130.       if(zipfile != NULL) fclose(zipfile);
  131.       ++*name;
  132.       if(!(zipfile = fopen(name,"w"))) {
  133.     perror(name);
  134.     exit(errno);
  135.       }
  136.       /*  Write headers. \041 \041 is a disk ID I think */
  137.             
  138.       if(i==0) fputs("\376\003\041\041",zipfile);
  139.       else fprintf(zipfile,"%c%c",0,4);
  140.     }
  141. return(0);
  142. }
  143.  
  144.  
  145. init_stuff(char *name)
  146. {
  147.   int i;
  148.  
  149.   for(i=0; i<17; max_sector[i++]=20);
  150.   for(i=17; i<24; max_sector[i++]=18);
  151.   for(i=24; i<30; max_sector[i++]=17);
  152.   for(i=30; i<35; max_sector[i++]=16);
  153.    
  154.   if(!(imgfile = fopen(name,"r"))) {
  155.     perror(name);
  156.     exit(errno);
  157.   }
  158.   else {
  159.     if(fread(image_buffer,1,sizeof(image_buffer),imgfile) 
  160.        != sizeof(image_buffer)) {
  161.       fprintf(stderr,"D64 image could be wrong size!\n");
  162.       exit(1);
  163.     }
  164.     close(imgfile);
  165.   }
  166. return(0);
  167. }
  168.  
  169. repeat_t rep_scan(byte *sec_buf)
  170. {
  171.   int i,j,count;
  172.   char table[256];
  173.  
  174.   rle_len=256;
  175.   num_repeats=0;
  176.       
  177.   for(i=0; i<255; i++) {
  178.     count=0;
  179.     while(i<255 && *(sec_buf+i)==*(sec_buf+i+1)) {
  180.       i++,count++;
  181.     }
  182.     if(count >= 3) {
  183.       rep_info[num_repeats].startpos=i-count;
  184.       rep_info[num_repeats].len=count+1;
  185.       ++num_repeats;
  186.     }         
  187.   }
  188.   if(num_repeats==0) return NONE;
  189.   else
  190.     if(count==255) return WHOLE;
  191.  
  192.   /*  VARIABLE  */
  193.  
  194.   rle_len += num_repeats*3;
  195.   for(i=0; i< num_repeats; i++)
  196.     rle_len -= rep_info[i].len;
  197.   if(rle_len >253) return NONE;
  198.       
  199.   for(j=0; j<256; table[j++]=1);
  200.   for(j=0; j<256;  table[*(sec_buf+j++)]=0);
  201.   for(j=0; j<256 && table[j]==0; j++);
  202.   repchar = j;
  203.    
  204. #ifdef EBUG1
  205.   printf("\nRepeats: %2u RLE_len: %3u Repchar: %3u\n",i,rle_len,j);
  206.   for(j=0;j<i;j++)
  207.     printf("Start: %3u Length: %3u\n",rep_info[j].startpos,rep_info[j].len);
  208. #endif   
  209.   return VARIABLE;   
  210. }
  211.