Beispiel #1
0
/*************************************************************************
**************************************************************************
#cat:   decode_tagged_field_image() - Takes an ANSI/NIST tagged field
#cat:                image record and decodes its image data (if necessary)
#cat:                and returns the reconstructed pixmap and its attributes.

   Input:
      ansi_nist   - ANSI/NIST file structure
      imgrecord_i - index of record to be decoded
      intrlvflag  - if image data is RGB, then this flagged designates
                    whether the returned pixmap should be interleaved or not
   Output:
      odata  - points to reconstructed pixmap
      ow     - pixel width of pixmap
      oh     - pixel height of pixmap
      od     - pixel depth of pixmap
      oppmm  - scan resolution of pixmap in pixels/mm
   Return Code:
      TRUE     - successful image reconstruction
      FALSE    - image record ignored
      Negative - system error
**************************************************************************/
int decode_tagged_field_image(unsigned char **odata,
                     int *ow, int *oh, int *od, double *oppmm,
                     const ANSI_NIST *ansi_nist, const int imgrecord_i,
                     const int intrlvflag)
{
   int i, ret;
   RECORD *imgrecord;
   FIELD *field;
   int field_i;
   char *img_comp, *img_csp;
   unsigned char *idata1, *idata2;
   int ilen1, iw1, ih1, id1;
   double ppmm;
   int ilen2, iw2, ih2, id2, ppi, lossyflag;
   IMG_DAT *img_dat;
   int hor_sampfctr[MAX_CMPNTS], vrt_sampfctr[MAX_CMPNTS];
   int n_cmpnts;

   /* If image record index is out of range ... */
   if((imgrecord_i < 1) || (imgrecord_i > ansi_nist->num_records)){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "record index [%d] out of range [1..%d]\n",
              imgrecord_i+1, ansi_nist->num_records+1);
      return(-2);
   }

   /* Set image record pointer. */
   imgrecord = ansi_nist->records[imgrecord_i];

   /* If NOT Type-10,13,14,15,16 ... */
   if(tagged_image_record(ansi_nist->records[imgrecord_i]->type) == 0){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "record index [%d] [Type-%d] is not a tagged file image record\n",
              imgrecord_i+1, imgrecord->type);
      return(-3);
   }

   /* 1. Determine Compression */
   /* Lookup grayscale compression algorithm (TAG_CA_ID). */
   if(lookup_ANSI_NIST_field(&field, &field_i, TAG_CA_ID, imgrecord) == 0){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "TAG_CA field not found in record index [%d] [Type-%d.%03d]\n",
              imgrecord_i+1, imgrecord->type, TAG_CA_ID);
      return(-4);
   }
   img_comp = (char *)field->subfields[0]->items[0]->value;

   /* 2. Determine image W */
   /* Lookup horizontal line length (HLL_ID). */
   if(lookup_ANSI_NIST_field(&field, &field_i, HLL_ID, imgrecord) == 0){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "HLL field not found in record index [%d] [Type-%d.%03d]\n",
              imgrecord_i+1, imgrecord->type, HLL_ID);
      return(-5);
   }
   iw1 = atoi((char *)field->subfields[0]->items[0]->value);

   /* 3. Determine image H */
   /* Lookup vertical line length (VLL_ID). */
   if(lookup_ANSI_NIST_field(&field, &field_i, VLL_ID, imgrecord) == 0){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "VLL field not found in record index [%d] [Type-%d.%03d]\n",
              imgrecord_i+1, imgrecord->type, VLL_ID);
      return(-6);
   }
   ih1 = atoi((char *)field->subfields[0]->items[0]->value);

   /* 4. Determine pixel depth */
   /* Lookup bits per pixel or colorspace (BPX_ID==CSP_ID). */
   if(lookup_ANSI_NIST_field(&field, &field_i, BPX_ID, imgrecord) == 0){
      fprintf(stderr, "ERROR : decode_tagged_field_image : "
	      "BPX field not found in record index [%d] [Type-%d.%03d]\n",
              imgrecord_i+1, imgrecord->type, BPX_ID);
      return(-7);
   }
   /* if Type-10 & 17... */
   if((imgrecord->type == TYPE_10_ID) || (imgrecord->type == TYPE_17_ID)){
      if (imgrecord->type == TYPE_10_ID){
      /* Grayscale? CSP_ID = 12, "GRAY" */
         if(lookup_ANSI_NIST_field(&field, &field_i, CSP_ID, imgrecord) == 0){
            fprintf(stderr, "ERROR : dpyan2k_tagged_record : "
		    "CSP field in record index [%d] [Type-%d.%03d] not found\n",
                    imgrecord_i+1, imgrecord->type, CSP_ID);
            return(-2);  
         }               
      }     
      if (imgrecord->type == TYPE_17_ID){
      /* Grayscale? CSP_ID_Type_17 = 13, "GRAY" */
         if(lookup_ANSI_NIST_field(&field, &field_i, CSP_ID_Type_17, imgrecord)
	    == 0){
            fprintf(stderr, "ERROR : dpyan2k_tagged_record : "
		    "CSP field in record index [%d] [Type-%d.%03d] not found\n",
                    imgrecord_i+1, imgrecord->type, CSP_ID_Type_17);
            return(-2);
         } 
      }    

      img_csp = (char *)field->subfields[0]->items[0]->value;
      if(strcmp(img_csp, CSP_GRAY) == 0)
         /* Set grayscale image attributes. */
         id1 = 8;
      else if((strcmp(img_csp, CSP_RGB) == 0) || 
              (strcmp(img_csp, CSP_YCC) == 0) ||
              (strcmp(img_csp, CSP_SRGB) == 0) ||
              (strcmp(img_csp, CSP_SYCC) == 0))
         /* Set color image attributes. */
         id1 = 24;
      /* Otherwise, unsupported color space, so ignore image record. */
      else{
         fprintf(stderr, "WARNING : decode_tagged_field_image : "
		 "colorspace \"%.10s%s\" not supported in "
		 "in record [%d] [Type-%d.%03d].\n"
		 "Image record ignored.\n", 
		 img_csp, strlen(img_csp) > 10 ? "..." : "",
		 imgrecord_i+1, imgrecord->type, CSP_ID);
         return(FALSE);
      }
   }
   /* Otherwise, Type-13,14,15,16 ... so current value == BPX_ID. */
   else{
      /* Set image pixel depth = BPX_ID. */
      id1 = atoi((char *)field->subfields[0]->items[0]->value);
   }

   /* 5. Determine ppmm */
   /* Lookup image record's pixel/mm scan resolution. */
   ret = lookup_tagged_field_image_ppmm(&ppmm, imgrecord);
   /* If error or IGNORE ... */
   if(ret <= 0)
      return(ret);

   /* Set image pointer to last field value in record. */
   field = imgrecord->fields[imgrecord->num_fields-1];
   idata1 = field->subfields[0]->items[0]->value;
   ilen1 = field->subfields[0]->items[0]->num_bytes;

   /* If the image data is uncompressed ... */
   if(strcmp(img_comp, COMP_NONE) == 0){
      idata2 = (unsigned char *)malloc((size_t)ilen1);
      if(idata2 == NULL){
         fprintf(stderr, "ERROR : decode_tagged_field_image : "
		 "malloc : idata2 (%d bytes)\n", ilen1);
         return(-8);
      }
      memcpy(idata2, idata1, (size_t)ilen1);

      /* For uncompressed RGB, the ANSI/NIST Standard dictates that */
      /* the pixels will be stored noninterleaved in 3 separate     */
      /* component planes. */
      /* So, if flag set to interleaved ... */
      if((id1 == 24) && (intrlvflag != 0)){
         /* There is no downsampling of RGB planes. */
         n_cmpnts = 3;
         for(i = 0; i < n_cmpnts; i++){
            hor_sampfctr[i] = 1;
            vrt_sampfctr[i] = 1;
         }
         if((ret = not2intrlv_mem(&idata1, &ilen1, idata2, iw1, ih1, id1,
				  hor_sampfctr, vrt_sampfctr, n_cmpnts)) != 0){
            free(idata2);
            return(ret);
         }
         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }

      *odata = idata2;
      *ow = iw1;
      *oh = ih1;
      *od = id1;
      *oppmm = ppmm;

      return(TRUE);
   }
   /* If WSQ compressed ... */
   else if(strcmp(img_comp, COMP_WSQ) == 0){
      if((ret = wsq_decode_mem(&idata2, &iw2, &ih2, &id2, &ppi, &lossyflag,
                              idata1, ilen1)) != 0)
         return(ret);
   }
#if 0
   /* If JPEGB compressed ... */
   else if(strcmp(img_comp, COMP_JPEGB) == 0){
      if((ret = jpegb_decode_mem(&idata2, &iw2, &ih2, &id2, &ppi, &lossyflag,
                                 idata1, ilen1)) != 0)
         return(ret);
      /* For 3 component color, JPEGB's decoder returns interleaved RGB. */
      /* So, if flag set to NOT interleaved ... */
      if((id2 == 24) && (intrlvflag == 0)){
         /* There is no downsampling of RGB planes. */
         n_cmpnts = 3;
         for(i = 0; i < n_cmpnts; i++){
            hor_sampfctr[i] = 1;
            vrt_sampfctr[i] = 1;
         }
         if((ret = intrlv2not_mem(&idata1, &ilen1, idata2, iw2, ih2, id2,
                                 hor_sampfctr, vrt_sampfctr, n_cmpnts)) != 0){
            free(idata2);
            return(ret);
         }
         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }
   }
#endif
#if 0
   /* If JPEGL compressed ... */
   else if(strcmp(img_comp, COMP_JPEGL) == 0){
      if((ret = jpegl_decode_mem(&img_dat, &lossyflag, idata1, ilen1)) != 0)
         return(ret);
      if((ret = get_IMG_DAT_image(&idata2, &ilen2, &iw2, &ih2, &id2, &ppi,
                                 img_dat)) != 0){
         free_IMG_DAT(img_dat, FREE_IMAGE);
         return(ret);
      }
      /* For 3 component color, JPEGL's decoder returns non-interleaved  */
      /* components planes.  So, if flag set to interleaved ...          */
      if((id2 == 24) && (intrlvflag != 0)){
         /* Note that this is set up to handle downsampled Cb and Cr planes */
         /* if the units encoded were in the YCbCr color space.  However    */
         /* the color space would need to be converted to RGB upon return   */
         /* of this routine. */
         /* The operational assumption is that the encoded color space */
         /* was RGB. */
         if((ret = not2intrlv_mem(&idata1, &ilen1, idata2,
                                 img_dat->max_width, img_dat->max_height,
                                 img_dat->pix_depth, img_dat->hor_sampfctr,
                                 img_dat->vrt_sampfctr, img_dat->n_cmpnts)) !=0){
            free_IMG_DAT(img_dat, FREE_IMAGE);
            free(idata2);
            return(ret);
         }

         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }
      free_IMG_DAT(img_dat, FREE_IMAGE);
   }
#endif
#if 0 /*__NBIS_JASPER__*/
   /* If JPEG2K compress ... */
   else if((strcmp(img_comp, COMP_JPEG2K) == 0) || 
           (strcmp(img_comp, COMP_JPEG2KL) == 0)){
      /* JPEG2K decoder always return 3 components planes. */
      /* id1 = 24; -- What's in the record has already been copied
	              into id1, and it isn't necessarily 24 - jck */
 
      if((ret = jpeg2k_decode_mem(&img_dat, &lossyflag, idata1, ilen1)) != 0)
         return(ret);
  
      if((ret = get_IMG_DAT_image(&idata2, &ilen2, &iw2, &ih2, &id2, &ppi,
                                 img_dat)) != 0){
         free_IMG_DAT(img_dat, FREE_IMAGE);
         return(ret);
      }
      /* For 3 component color, JPEG2K's decoder returns non-interleaved  */
      /* components planes.  So, if flag set to interleaved ...          */
      if((id2 == 24) && (intrlvflag != 0)){
         if((ret = not2intrlv_mem(&idata1, &ilen1, idata2,
                                  img_dat->max_width, img_dat->max_height,
                                  img_dat->pix_depth, img_dat->hor_sampfctr,
                                  img_dat->vrt_sampfctr, img_dat->n_cmpnts)) != 0){
            free_IMG_DAT(img_dat, FREE_IMAGE);
            free(idata2);
            return(ret);

         }
         free_IMG_DAT(img_dat, FREE_IMAGE);
         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }
   }
#endif
#if 0 /*__NBIS_OPENJPEG__*/
   /* If JPEG2K compress ... */
   else if((strcmp(img_comp, COMP_JPEG2K) == 0) ||
           (strcmp(img_comp, COMP_JPEG2KL) == 0)){
      /* JPEG2K decoder always return 3 components planes. */
      /* id1 = 24; -- What's in the record has already been copied
                      into id1, and it isn't necessarily 24 - jck */

      if((ret = openjpeg2k_decode_mem(&img_dat, &lossyflag, idata1, ilen1)) != 0)
         return(ret);
 
      if((ret = get_IMG_DAT_image(&idata2, &ilen2, &iw2, &ih2, &id2, &ppi,
                                 img_dat)) != 0){
         free_IMG_DAT(img_dat, FREE_IMAGE);
         return(ret);
      }
      /* For 3 component color, JPEG2K's decoder returns non-interleaved  */
      /* components planes.  So, if flag set to interleaved ...          */
      if((id2 == 24) && (intrlvflag != 0)){
         if((ret = not2intrlv_mem(&idata1, &ilen1, idata2,
                                  img_dat->max_width, img_dat->max_height,
                                  img_dat->pix_depth, img_dat->hor_sampfctr,
                                  img_dat->vrt_sampfctr, img_dat->n_cmpnts)) != 0){
            free_IMG_DAT(img_dat, FREE_IMAGE);
            free(idata2);
            return(ret);

         }
         free_IMG_DAT(img_dat, FREE_IMAGE);
         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }
   }
#endif
#if 0 /*__NBIS_PNG__*/
   /* If PNG compressed ... */
   else if(strcmp(img_comp, COMP_PNG) == 0){
      if((ret = png_decode_mem(&img_dat, &lossyflag, idata1, ilen1)) != 0)
         return(ret);
      if((ret = get_IMG_DAT_image(&idata2, &ilen2, &iw2, &ih2, &id2, &ppi,
                                 img_dat)) != 0){
         free_IMG_DAT(img_dat, FREE_IMAGE);
         return(ret);
      }
      /* For 3 component color, PNG's decoder returns non-interleaved  */
      /* components planes.  So, if flag set to interleaved ...          */
      if((id2 == 24) && (intrlvflag != 0)){
         if((ret = not2intrlv_mem(&idata1, &ilen1, idata2,
                                  img_dat->max_width, img_dat->max_height,
                                  img_dat->pix_depth, img_dat->hor_sampfctr,
                                  img_dat->vrt_sampfctr, img_dat->n_cmpnts)) !=  0){
            free_IMG_DAT(img_dat, FREE_IMAGE); 
            free(idata2);
            return(ret);
         }
         free_IMG_DAT(img_dat, FREE_IMAGE);
         free(idata2);
         idata2 = idata1;
         ilen2 = ilen1;
      }
   }
#endif
   /* Otherwise, unsupported compression algorithm. */
   else{
      fprintf(stderr, "WARNING : decode_tagged_field_image : "
	      "unsupported compression algorithm %.10s%s in "
	      "image record index [%d] [Type-%d].\n"
	      "Image record ignored.\n",
              img_comp, strlen(img_comp) > 10 ? "..." : "",
              imgrecord_i+1, imgrecord->type);
      /* Ignore image record ... */
      return(FALSE);
   }

   /* Code change by MDG on 07/02/04 to handle discrepancies in   */
   /* image records where the values in fields HLL and VLL differ */
   /* from what was actually decoded from the compressed image    */
   /* block.  In these cases, we post a warning and then set      */
   /* image attributes to be consistent with what was decoded.    */
   if(iw1 != iw2){
      fprintf(stderr, "WARNING : decode_tagged_field_image : "
	      "[HLL field (from file) = %d] != "
	      "[image width (from decoder) = %d]\n"
	      "Will continue with operating assumption "
	      "that image width is %d\n", iw1, iw2, iw2);
      iw1 = iw2;
   }
   if(ih1 != ih2){
      fprintf(stderr, "WARNING : decode_tagged_field_image : "
	      "[VLL field (from file) = %d] != "
	      "[image height (from decoder) = %d]\n"
	      "Will continue with operating assumption "
	      "that image height is %d\n", ih1, ih2, ih2);
      ih1 = ih2;
   }
   if(id1 != id2){
      fprintf(stderr, "WARNING : decode_tagged_field_image : "
	      "[pixel depth (from field value) = %d] != "
	      "[pixel depth (from decoder) = %d]\n"
	      "Will continue with operating assumption "
	      "that image depth is %d\n", id1, id2, id2);
      id1 = id2;
   }

   *odata = idata2;
   *ow = iw1;
   *oh = ih1;
   *od = id1;
   *oppmm = ppmm;

   return(TRUE);
}
Beispiel #2
0
int main(int argc, char *argv[])
{
   int ret, n, rawflag;
   char *outext;                   /* ouput file extension */
   char *ifile, ofile[MAXPATHLEN]; /* file names */
   FILE *outfp;                    /* output file pointer */
   int  width, height, depth, ppi, ilen, olen;  /* image parameters */
   unsigned char *idata, *odata;           /* image pointers */
   int hor_sampfctr[MAX_CMPNTS], vrt_sampfctr[MAX_CMPNTS];
   int n_cmpnts;
   int fsize;


   procargs(argc, argv, &outext, &ifile,
            &width, &height, &depth, &ppi, &rawflag,
            hor_sampfctr, vrt_sampfctr, &n_cmpnts);

   if((ret = filesize(ifile)) < 0)
      exit(ret);
   fsize = ret;

   if((ret = test_image_size(fsize, width, height, hor_sampfctr,
                            vrt_sampfctr, n_cmpnts, 0)))
      exit(ret);

   if((ret = read_raw_from_filesize(ifile, &idata, &ilen)))
      exit(ret);

   if(debug > 0)
      fprintf(stdout, "File %s read\n", ifile);


   if((ret = not2intrlv_mem(&odata, &olen, idata, width, height, depth,
                           hor_sampfctr, vrt_sampfctr, n_cmpnts))){
      free(idata);
      exit(ret);
   }
   free(idata);

   if(debug > 0)
      fprintf(stdout, "Image data converted to interleaved\n");

   /* Write interleaved image file. */
   fileroot(ifile);
   sprintf(ofile, "%s.%s", ifile, outext);

   /* If H,V's are specified on command line, then YCbCr ... */
   /* so write a raw output file. */
   if(argc == 7){
      if((outfp = fopen(ofile, "wb")) == NULL) {
         fprintf(stderr, "ERROR: main : fopen : %s\n",ofile);
         free(odata);
         exit(-5);
      }

      if((n = fwrite(odata, 1, olen, outfp)) != olen){
         fprintf(stderr, "ERROR: main : fwrite : ");
         /* MDG added '%' to 's' to fix syntax error on 05/09/2005 */
         fprintf(stderr, "only %d of %d bytes written from file %s\n",
                 n, olen, ofile);
         free(odata);
         exit(-6);
      }
      fclose(outfp);
   }
   /* Otherwise, H,V's not specified on command line, so component planes */
   /* are all the same size ... so "possibly" write an IHead file. */
   else{
      if((ret = write_raw_or_ihead(!rawflag, ofile,
                                  odata, width, height, depth, ppi))){
         free(odata);
         exit(ret);
      }
   }

   if(debug > 0)
      fprintf(stdout, "Image data written to file %s\n", ofile);

   free(odata);

   exit(0);
}