void MainWindow::open() { QString file = QFileDialog::getOpenFileName(this, tr("qwsqviewer"), QString(), tr("Wsq images (*.wsq)")); if (file.isEmpty()) return; unsigned char *idata; int ilen; int ret; if ((ret = read_raw_from_filesize(file.toLocal8Bit().data(), &idata, &ilen))) { free(idata); QMessageBox::warning(this, tr("qwsqviewer"), tr("failed.")); return; } unsigned char* odata; int width, height, depth, ppi, lossyflag; if ((ret = wsq_decode_mem(&odata, &width, &height, &depth, &ppi, &lossyflag, idata, ilen))) { free(idata); QMessageBox::warning(this, tr("qwsqviewer"), tr("failed 2.")); return; } QImage img(odata, width, height, QImage::Format_Grayscale8, &free, odata); _canvas->setImage(img); _canvas->update(); _canvas->setPpi(ppi); free(idata); }
NISTWSQ_API int __cdecl wsq_decode( byte** decompressed_data, int* width, int* height, int* depth, int* pixels_per_inch, int* lossy_flag, byte* wsq_data, int wsq_data_length) { return wsq_decode_mem( decompressed_data, width, height, depth, pixels_per_inch, lossy_flag, wsq_data, wsq_data_length); }
int main( int argc, char **argv) { int ret; int rawflag; /* raw input data or Ihead image */ char *outext; /* ouput file extension */ char *ifile, ofile[MAXPATHLEN]; /* file names */ int ilen; int width, height; /* image parameters */ int depth, ppi; unsigned char *idata, *odata; /* image pointers */ int lossyflag; /* data loss flag */ NISTCOM *nistcom; /* NIST Comment */ char *ppi_str; procargs(argc, argv, &outext, &ifile, &rawflag); ret = read_raw_from_filesize(ifile, &idata, &ilen); if(ret) exit(ret); ret = wsq_decode_mem(&odata, &width, &height, &depth, &ppi, &lossyflag, idata, ilen); if(ret){ free(idata); exit(ret); } if(debug > 1) fprintf(stderr, "Image pixmap constructed\n"); fileroot(ifile); sprintf(ofile, "%s.%s", ifile, NCM_EXT); /* Get NISTCOM from compressed data file */ ret = getc_nistcom_wsq(&nistcom, idata, ilen); if(ret){ free(idata); exit(ret); } free(idata); /* WSQ decoder always returns ppi=-1, so believe PPI in NISTCOM, */ /* if it already exists. */ ppi_str = (char *)NULL; if(nistcom != (NISTCOM *)NULL){ ret = extractfet_ret(&ppi_str, NCM_PPI, nistcom); if(ret){ free(odata); freefet(nistcom); exit(ret); } } if(ppi_str != (char *)NULL){ ppi = atoi(ppi_str); free(ppi_str); } /* Combine NISTCOM with image features */ ret = combine_wsq_nistcom(&nistcom, width, height, depth, ppi, lossyflag, 0.0 /* will be deleted next */); if(ret){ free(odata); if(nistcom != (NISTCOM *)NULL) freefet(nistcom); exit(ret); } ret = del_wsq_nistcom(nistcom); if(ret){ free(odata); freefet(nistcom); exit(ret); } /* Write NISTCOM */ ret = writefetfile_ret(ofile, nistcom); if(ret){ free(odata); freefet(nistcom); exit(ret); } freefet(nistcom); /* Write decoded image file. */ sprintf(ofile, "%s.%s", ifile, outext); ret = write_raw_or_ihead(!rawflag, ofile, odata, width, height, depth, ppi); if(ret){ free(odata); exit(ret); } free(odata); if(debug > 1) fprintf(stdout, "Image pixmap written to %s\n", ofile); exit(0); }
/** * Decodes an encoded WSQ byte array to a buffered image. * Based on dwsq.c. * * @param in a byte array holding the encoded WSQ image * * @return a buffered image */ JNIEXPORT jobject JNICALL Java_org_jmrtd_imageio_WSQImageReader_decodeWSQ (JNIEnv *env, jobject obj, jbyteArray in, jobject metadata) { /* Java classes and objects */ jclass ioexceptionClazz = (*env)->FindClass(env, "java/io/IOException"); jclass metadataClazz = (*env)->GetObjectClass(env, metadata); jclass imgClazz = (*env)->FindClass(env, "java/awt/image/BufferedImage"); jclass writableRasterClazz = (*env)->FindClass(env, "java/awt/image/WritableRaster"); jmethodID metadataSetPropertyMethodID = (*env)->GetMethodID(env, metadataClazz, "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Z"); jmethodID imgInitMethodID = (*env)->GetMethodID(env, imgClazz, "<init>", "(III)V"); jmethodID imgGetRasterMethodID = (*env)->GetMethodID(env, imgClazz, "getRaster", "()Ljava/awt/image/WritableRaster;"); jmethodID rasterSetDataElementsMethodID = (*env)->GetMethodID(env, writableRasterClazz, "setDataElements", "(IIIILjava/lang/Object;)V"); jfieldID imgTypeByteGrayFieldID = (*env)->GetStaticFieldID(env, imgClazz, "TYPE_BYTE_GRAY", "I"); jint TYPE_BYTE_GRAY = (*env)->GetStaticIntField(env, imgClazz, imgTypeByteGrayFieldID); jobject imgObject, rasterObject; /* WSQ-Compressed input buffer */ unsigned char *idata = (unsigned char*)(*env)->GetByteArrayElements(env, in, JNI_FALSE); int idata_len = (*env)->GetArrayLength(env, in); /* Uncompressed Pixel Buffer */ unsigned char *odata = NULL; jbyteArray jodata = NULL; /* Image parameters */ NISTCOM *nistcom = NULL; int width, height, depth, ppi, lossy; int wsq_decore_ret, nistcom_ret; /* Parse WSQ Image */ wsq_decore_ret = wsq_decode_mem(&odata, &width, &height, &depth, &ppi, &lossy, idata, idata_len); if (wsq_decore_ret==0) { jodata = (*env)->NewByteArray(env, width*height); (*env)->SetByteArrayRegion(env, jodata, 0, width*height, (jbyte*)odata); free(odata); odata = NULL; } else { (*env)->ReleaseByteArrayElements(env, in, (jbyte*)idata, JNI_FALSE); (*env)->ThrowNew(env, ioexceptionClazz, "(In native C code) function wsq_decode_mem failed"); return NULL; } /* WSQ Metadata */ nistcom_ret = getc_nistcom_wsq(&nistcom, idata, idata_len); if (nistcom_ret==0 && nistcom != NULL) { int i; for (i=0; i<nistcom->num; i++) { if (nistcom->names[i]) { (*env)->CallBooleanMethod( env, metadata, metadataSetPropertyMethodID, (*env)->NewStringUTF(env, nistcom->names[i]), nistcom->values[i] ? (*env)->NewStringUTF(env, nistcom->values[i]) : NULL ); } } freefet(nistcom); } (*env)->ReleaseByteArrayElements(env, in, (jbyte*)idata, JNI_FALSE); /* Construct a BufferedImage from the byte array: BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); WritableRaster raster = img.getRaster(); raster.setDataElements(0, 0, width, height, decodedBytes); */ imgObject = (*env)->NewObject(env, imgClazz, imgInitMethodID, width, height, TYPE_BYTE_GRAY); rasterObject = (*env)->CallObjectMethod(env, imgObject, imgGetRasterMethodID); (*env)->CallVoidMethod(env, rasterObject, rasterSetDataElementsMethodID, 0, 0, width, height, jodata); return imgObject; }
/************************************************************************* ************************************************************************** #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); }
/************************************************************************* ************************************************************************** #cat: decode_binary_field_image() - Takes an ANSI/NIST binary 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 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_binary_field_image(unsigned char **odata, int *ow, int *oh, int *od, double *oppmm, const ANSI_NIST *ansi_nist, const int imgrecord_i) { int ret; RECORD *imgrecord; FIELD *field; int field_i; char *img_comp; unsigned char *idata1, *idata2; int ilen, iw1, ih1, id1; double ppmm; int iw2, ih2, id2, ppi, lossyflag; /* If image record index is out of range ... */ if((imgrecord_i < 1) || (imgrecord_i > ansi_nist->num_records)){ fprintf(stderr, "ERROR : decode_binary_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 for some reason someone's passes a Type-8 record ... */ if(imgrecord->type == TYPE_8_ID){ /* Post warning and ignore record Type-8. */ fprintf(stderr, "WARNING : decode_binary_field_image : " "Type-8 record [%d] not supported.\n" "Image record ignored.\n", imgrecord_i+1); return(FALSE); } /* 1. Determine Compression */ /* Lookup binary compression algorithm (BIN_CA_ID). */ if(lookup_ANSI_NIST_field(&field, &field_i, BIN_CA_ID, imgrecord) == 0){ fprintf(stderr, "ERROR : decode_binary_field_image : " "BIN_CA field not found in record index [%d] [Type-%d.%03d]\n", imgrecord_i+1, imgrecord->type, BIN_CA_ID); return(-3); } img_comp = (char *)field->subfields[0]->items[0]->value; /* If Type-5,6 ... ignore if compressed. */ if((imgrecord->type == TYPE_5_ID) || (imgrecord->type == TYPE_6_ID)){ /* If the image data is compressed ... */ if(strcmp(img_comp, BIN_COMP_NONE) != 0){ fprintf(stderr, "WARNING : decode_binary_field_image : " "binary image compression of " "record index [%d] [Type-%d] is unsupported.\n" "Image record ignored.\n", imgrecord_i+1, imgrecord->type); /* Ignore image record ... */ return(FALSE); } } /* 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_binary_field_image : " "HLL field not found in record index [%d] [Type-%d.%03d]\n", imgrecord_i+1, imgrecord->type, HLL_ID); return(-4); } 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_binary_field_image : " "VLL field not found in record index [%d] [Type-%d.%03d]\n", imgrecord_i+1, imgrecord->type, VLL_ID); return(-5); } ih1 = atoi((char *)field->subfields[0]->items[0]->value); /* 4. Determine pixel depth */ switch(imgrecord->type){ case TYPE_3_ID: case TYPE_4_ID: /* Image record is grayscale, so set pixel depth = 8. */ id1 = 8; break; case TYPE_5_ID: case TYPE_6_ID: /* Image record is bi-level, so set pixel depth = 1. */ id1 = 1; break; default: fprintf(stderr, "ERROR : decode_binary_field_image : " "illegal binary image record type = %d\n", imgrecord->type); return(-6); } /* 5. Determine ppmm */ /* Lookup image record's pixel/mm scan resolution. */ if((ret = lookup_binary_field_image_ppmm(&ppmm, ansi_nist, imgrecord_i)) !=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; ilen = field->subfields[0]->items[0]->num_bytes; /* If the image data is uncompressed ... */ if(strcmp(img_comp, BIN_COMP_NONE) == 0){ idata2 = (unsigned char *)malloc((size_t)ilen); if(idata2 == NULL){ fprintf(stderr, "ERROR : decode_binary_field_image : " "malloc : idata2 (%d bytes)\n", ilen); return(-7); } memcpy(idata2, idata1, (size_t)ilen); *odata = idata2; *ow = iw1; *oh = ih1; *od = id1; *oppmm = ppmm; return(TRUE); } /* Otherwise, binary field image data is compressed ... */ /* If WSQ compressed ... */ else if(strcmp(img_comp, BIN_COMP_WSQ) == 0){ if((ret = wsq_decode_mem(&idata2, &iw2, &ih2, &id2, &ppi, &lossyflag, idata1, ilen)) != 0) return(ret); } /* Otherwise, unsupported compression algorithm. */ else{ fprintf(stderr, "WARNING : decode_binary_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); } if(iw1 != iw2){ fprintf(stderr, "ERROR : decode_binary_field_image : " "[HLL field (from file) = %d] != " "[image width (from decoder) = %d]\n", iw1, iw2); free(idata2); return(-8); } if(ih1 != ih2){ fprintf(stderr, "ERROR : decode_binary_field_image : " "[VLL field (from file) = %d] != " "[image height (from decoder) = %d]\n", ih1, ih2); free(idata2); return(-9); } if(id1 != id2){ fprintf(stderr, "ERROR : decode_binary_field_image : " "[pixel depth (from record Type-%d) = %d] != " "[pixel depth (from decoder) = %d]\n", id2, imgrecord->type, id1); free(idata2); return(-10); } *odata = idata2; *ow = iw1; *oh = ih1; *od = id1; *oppmm = ppmm; return(TRUE); }