Haider85 0 Newbie Poster

I have a Health based .Net (C#) project that needs to import a huge chunk of medical records from an old database that were used in a different application. The database has been successfully migrated to the version compatible with our application. The problem is the contents in one of its table. It contains binary data, that we have concluded so far is in a 'compressed' form. The compression method used is an algo found here:

Simple Compression Zip - https://sourceforge.net/projects/scz-compress/

In order to view (the binary are compressed form of PDFs and Images) the compressed files, we need to de-compress them first.

According to the link above, the SCZ provides the code (C language) that can do that and we have successfully used it to compress a standard image to SCZ file and then back to its original state. But, the issue lies with the contents of the data in the table, as I mentioned before, it is in binary (not physical SCZ file). The C code on the site does have overload methods for decompression of binary but since we don't do C, we are unable to use them as required. What we want to achieve is either:

Use the C code and compile it to a dll that can be used in our .Net C# project
Use the C code and translate it to C# code that accepts the binary (from the database) and converts it to the original decompressed file
I have tried to contact the original developer of the algorithm, but the email bounced.

Here is the code for the console application I was able to develop for compression and decompression (of file), I simply require a version (or equivalent C# code) that accepts the binary directly and outputs the decomperssed file: The referenced files can be found on the link above

Compression

--- main.c ---
int main( int argc, char *argv[] )
{
 char outfname[4096];
 int j, k, verbose=0;

 /* Get the command-line arguments. */
 j = 1;  k = 0;
 while (argc>j)
  { /*argument*/
   if (argv[j][0]=='-')
    { /*optionflag*/
     if (strcasecmp(argv[j],"-v")==0) verbose = 1;
     else
     if (strcasecmp(argv[j],"-b")==0) 
      {
    j++;
    if (j==argc) {printf("Missing -b blocksize value.\n"); exit(0);}
    if (sscanf(argv[j],"%d",&sczbuflen)!=1) {printf("Bad -b blocksize value '%s'.\n",argv[j]); exit(0);}
      }
     else {printf("\nERROR:  Unknown command line option /%s/.\n", argv[j]); exit(0); }
    } /*optionflag*/
   else
    { /*file*/
     k = k + 1;
     if (strlen(argv[j])>4090) {printf("Error: file name too long.\n"); exit(0);}
     strcpy(outfname,argv[j]);  /* Append .scz suffix. */
     if (outfname[strlen(outfname)-1]=='.') outfname[strlen(outfname)-1] = '\0';
     strcat(outfname, ".scz");
     printf("\n Writing output to file %s\n", outfname);
     Scz_Compress_File( argv[j], outfname );    /* <--- Compress the file. */
    } /*file*/
   j = j + 1;
  } /*argument*/
 if (k==0) { printf("Error: Missing file name. Exiting."); exit(0); }

 return 0;
}
--- scz_compress_lib.c ---

int Scz_Compress_File( char *infilename, char *outfilename )
{
 struct scz_item *buffer0_hd=0, *buffer0_tl=0, *bufpt;
 int sz1=0, sz2=0, szi, success=1, flen, buflen;
 unsigned char ch, chksum;
 FILE *infile=0, *outfile=0;

 infile = fopen(infilename,"rb");
 if (infile==0) {printf("ERROR: Cannot open input file '%s'.  Exiting\n", infilename); exit(1);}

 outfile = fopen(outfilename,"wb");
 if (outfile==0) {printf("ERROR: Cannot open output file '%s' for writing.  Exiting\n", outfilename); exit(1);}

 flen = Scz_get_file_length( infile );
 buflen = flen / sczbuflen + 1;
 buflen = flen / buflen + 1;
 if (buflen>=SCZ_MAX_BUF) {printf("Error: Buffer length too large.\n"); exit(0);}

 /* Read file into linked list. */
 ch = getc(infile);
 while (!feof(infile))
  { /*outerloop*/

    chksum = 0;  szi = 0;
    buffer0_hd = 0;   buffer0_tl = 0;
    while ((!feof(infile)) && (szi < buflen))
     {
      scz_add_item( &buffer0_hd, &buffer0_tl, ch );
      sz1++;  szi++;  chksum += ch;  
      ch = getc(infile);
     }

   success = success & Scz_Compress_Seg( &buffer0_hd, szi );

   /* Write the file out. */
   while (buffer0_hd!=0)
    {
     fputc( buffer0_hd->ch, outfile );
     sz2++;
     bufpt = buffer0_hd;
     buffer0_hd = buffer0_hd->nxt;
     sczfree(bufpt);
    }
   fprintf(outfile,"%c", chksum); 
   sz2++;
   if (feof(infile)) fprintf(outfile,"]");  /* Place no-continuation marker. */
   else fprintf(outfile,"[");           /* Place continuation marker. */
   sz2++;

  } /*outerloop*/
 fclose(infile);
 fclose(outfile);

 printf("Initial size = %d,  Final size = %d\n", sz1, sz2);
 printf("Compression ratio = %g : 1\n", (float)sz1 / (float)sz2 );
 free(scz_freq2);
 scz_freq2 = 0;
 return success;
}

Decompression

--- main.c ---
int main( int argc, char *argv[] ) {
      char fname[4096], *suffix;
 int j=1, k=0, m, verbose=0;

 /* Get the command-line arguments. */
 while (argc>j)
  { /*argument*/
   if (argv[j][0]=='-')
    { /*optionflag*/
     if (strcasecmp(argv[j],"-v")==0) verbose = 1;
     else {printf("\nERROR:  Unknown command line option /%s/.\n", argv[j]); exit(0); }
    } /*optionflag*/
   else
    { /*file*/
     k = k + 1;
     /* Find final '.scz'.  Name must end with .scz.  Remove the .scz suffix. */
     m = strlen(argv[j]);
     if (m>4090) {printf("SCZ Error: file name too long.\n"); exit(0);}
     strcpy(fname,argv[j]);
     suffix = strstr(fname,".scz");
     if (suffix==0) printf("SCZ Warning: Skipping file not ending in '.scz', '%s'\n", argv[j]);
     else
      {
       suffix[0] = '\0';
       if (fname[0]=='\0') printf("SCZ Warning: File '%s' reduces to zero length name, skipping.\n",argv[j]);
       else
        Scz_Decompress_File( argv[j], fname );     /* <--- De-compress the file. */
      }
    } /*file*/
   j = j + 1;
  } /*argument*/
 if (k==0) { printf("Error: Missing file name.\n"); }
 return 0;
}



--- scz_decompress_lib.c ---
int Scz_Decompress_File2Buffer( char *infilename, char **outbuffer, int *M )
{
 int k, success, sz1=0, sz2=0, buflen, continuation, totalin=0, totalout=0;
 unsigned char ch, chksum, chksum0;
 struct scz_item *buffer0_hd, *buffer0_tl, *bufpt, *bufprv, *sumlst_hd=0, *sumlst_tl=0;
 FILE *infile=0;

 infile = fopen(infilename,"rb");
 if (infile==0) {printf("ERROR: Cannot open input file '%s'.  Exiting\n", infilename);  return 0;}

 do 
  { /*Segment*/

   /* Read file segment into linked list for expansion. */
   /* Get the 6-byte header to find the number of chars to read in this segment. */
   /*  (magic number (101), magic number (98), iter-count, seg-size (MBS), seg-size, seg-size (LSB). */ 
   buffer0_hd = 0;  buffer0_tl = 0;

   ch = getc(infile);   sz1++;      /* Byte 1, expect magic numeral 101. */
   if ((feof(infile)) || (ch!=101)) {printf("Error1: This does not look like a compressed file.\n"); return 0;}
   scz_add_item( &buffer0_hd, &buffer0_tl, ch );

   ch = getc(infile);  sz1++;       /* Byte 2, expect magic numeral 98. */
   if ((feof(infile)) || (ch!=98)) {printf("Error2: This does not look like a compressed file. (%d)\n", ch); return 0;}
   scz_add_item( &buffer0_hd, &buffer0_tl, ch );

   ch = getc(infile);  sz1++;       /* Byte 3, iteration-count. */
   if (feof(infile)) {printf("Error3: This does not look like a compressed file.\n"); return 0;}
   scz_add_item( &buffer0_hd, &buffer0_tl, ch );

   ch = getc(infile);           /* Byte 4, MSB of segment buffer length. */
   if (feof(infile)) {printf("Error3: This does not look like a compressed file.\n"); return 0;}
   buflen = ch << 16;
   ch = getc(infile);           /* Byte 5, middle byte of segment buffer length. */
   if (feof(infile)) {printf("Error3: This does not look like a compressed file.\n"); return 0;}
   buflen = (ch << 8) | buflen;
   ch = getc(infile);           /* Byte 6, LSB of segment buffer length. */
   if (feof(infile)) {printf("Error3: This does not look like a compressed file.\n"); return 0;}
   buflen = ch | buflen;

   k = 0;
   ch = getc(infile);
   while ((!feof(infile)) && (k<buflen))
    {
     scz_add_item( &buffer0_hd, &buffer0_tl, ch );
     sz1++;  k++;
     ch = getc(infile);
    }

   chksum0 = ch;
   ch = getc(infile);
   // printf("End ch = '%c'\n", ch);

   if (k<buflen) {printf("Error: Unexpectedly short file.\n");}
   totalin = totalin + sz1 + 4;     /* (+4, because chksum+3buflen chars not counted above.) */
   /* Decode the 'end-marker'. */
   if (ch==']') continuation = 0;
   else
   if (ch=='[') continuation = 1;
   else {printf("Error4: Reading compressed file. (%d)\n", ch);  return 0; }

   success = Scz_Decompress_Seg( &buffer0_hd ); /* Decompress the buffer !!! */
   if (!success) return 0;

   /* Check checksum and sum length. */
   sz2 = 0;       /* Get buffer size. */
   bufpt = buffer0_hd;
   chksum = 0;
   bufprv = 0;
   while (bufpt!=0)
    {
     chksum += bufpt->ch;
     sz2++;  bufprv = bufpt;
     bufpt = bufpt->nxt;
    }
   if (chksum != chksum0) {printf("Error: Checksum mismatch (%dvs%d)\n", chksum, chksum0);}

   /* Attach to tail of main list. */
   totalout = totalout + sz2;
   if (sumlst_hd==0) sumlst_hd = buffer0_hd;
   else sumlst_tl->nxt = buffer0_hd;
   sumlst_tl = bufprv;

  } /*Segment*/
 while (continuation);

 /* Convert list into buffer. */
 *outbuffer = (char *)malloc((totalout)*sizeof(char));
 sz2 = 0;
 while (sumlst_hd!=0)
  {
   bufpt = sumlst_hd;
   (*outbuffer)[sz2++] = bufpt->ch;
   sumlst_hd = bufpt->nxt;
   sczfree(bufpt);
  }
 if (sz2 > totalout) printf("Unexpected overrun error\n");

 *M = totalout;

 fclose(infile);
 printf("Decompression ratio = %g\n", (float)totalout / (float)totalin );
 return 1;
}

** Thanks for all the help.**