nitf_ImageSource *makeImageSource( test_nitf_ImageIOConstructArgs *args, char ***data) { nitf_ImageSource *imgSource; /* The result */ nitf_Uint32 nBands; /* Number of bands */ nitf_Off bandSize; /* Size of individual bands */ nitf_Error error; /* Error object argument */ nitf_Uint32 i; bandSize = (args->nRows) * (args->nColumns) * (NITF_NBPP_TO_BYTES(args->nBits)); imgSource = nitf_ImageSource_construct(&error); if (imgSource == NULL) { nitf_Error_print(&error, stderr, "Error setting up image source "); exit(EXIT_FAILURE); } nBands = args->nBands; if (nBands == 0) nBands = args->nMultiBands; for (i = 0;i < nBands;i++) { nitf_DataSource * bandSrc; /* Current band data source */ bandSrc = nitf_MemorySource_construct( &(data[i][0][0]), bandSize, 0, 0, 0, &error); if (bandSrc == NULL) { nitf_Error_print(&error, stderr, "Error setting up band source "); exit(EXIT_FAILURE); } if (!nitf_ImageSource_addBand(imgSource, bandSrc, &error)) { nitf_Error_print(&error, stderr, "Error setting up band source "); exit(EXIT_FAILURE); } } return(imgSource); }
NITF_BOOL readImageSegment(imgInfo *img, nitf_Reader *reader, nitf_Error *error) { nitf_Uint32 nBits; /* Bits/pixel */ nitf_Uint32 nBands; /* Number of bands */ nitf_Uint32 xBands; /* Number of extended bands */ nitf_Uint32 nRows; /* Number of rows */ nitf_Uint32 nColumns; /* Number of columns */ size_t subimageSize; /* Image band size in bytes */ nitf_SubWindow *subimage; /* Sub-image object specifying full image */ nitf_DownSampler *pixelSkip; /* Downsample for sub-window */ nitf_Uint32 *bandList; /* List of bands for read */ nitf_Uint32 band; /* Current band */ nitf_Uint8 **buffers; /* Read buffer one/band */ /* Image reader */ nitf_ImageReader *deserializer; int padded; /* Argument for read */ int i; /* Get dimension and band info */ nitf_Field_get(img->subhdr->numBitsPerPixel, &nBits, NITF_CONV_UINT, NITF_INT32_SZ, error); nitf_Field_get(img->subhdr->numImageBands, &nBands, NITF_CONV_UINT, NITF_INT32_SZ, error); nitf_Field_get(img->subhdr->numMultispectralImageBands, &xBands, NITF_CONV_UINT, NITF_INT32_SZ, error); nBands += xBands; nitf_Field_get(img->subhdr->numRows, &nRows, NITF_CONV_UINT, NITF_INT32_SZ, error); nitf_Field_get(img->subhdr->numCols, &nColumns, NITF_CONV_UINT, NITF_INT32_SZ, error); img->bytes = NITF_NBPP_TO_BYTES(nBits); subimageSize = nRows * nColumns * img->bytes; img->imgSize = subimageSize; /* Setup sub-window */ subimage = nitf_SubWindow_construct(error); if (subimage == NULL) return(NITF_FAILURE); bandList = (nitf_Uint32 *) NITF_MALLOC(sizeof(nitf_Uint32 *) * nBands); if (bandList == NULL) return(NITF_FAILURE); subimage->startCol = 0; subimage->startRow = 0; subimage->numRows = nRows; subimage->numCols = nColumns; for (band = 0;band < nBands;band++) bandList[band] = band; subimage->bandList = bandList; subimage->numBands = nBands; pixelSkip = nitf_PixelSkip_construct(1, 1, error); if (pixelSkip == NULL) return(NITF_FAILURE); if (!nitf_SubWindow_setDownSampler(subimage, pixelSkip, error)) return(NITF_FAILURE); /* Set-up buffers (one/band) */ buffers = (nitf_Uint8 **) NITF_MALLOC(nBands * sizeof(nitf_Uint8*)); if (buffers == NULL) return(NITF_FAILURE); for (i = 0;i < nBands;i++) { buffers[i] = (nitf_Uint8 *) malloc(subimageSize); if (buffers[i] == NULL) return(NITF_FAILURE); } deserializer = nitf_Reader_newImageReader(reader, img->index, error); if (deserializer == NULL) return(NITF_FAILURE); if (!nitf_ImageReader_read(deserializer, subimage, buffers, &padded, error)) return(NITF_FAILURE); img->nBands = nBands; img->buffers = buffers; return(NITF_SUCCESS); }
int doWrite(nitf_ImageSegment* segment, nitf_ImageSource *imgSrc, nitf_IOHandle output_io, nitf_ImageIO* ioClone) { nitf_Error error; nitf_Uint8** user; nitf_Uint32 nBits, nBands, xBands, nRows, nColumns, row; size_t rowSize; int band; NITF_BOOL success; /* Used in GET macros */ nitf_BandSource *bandSrc; /* Current band source object */ nitf_ImageSource *imgSrcTmp; GET_UINT32(segment->subheader->numBitsPerPixel, &nBits, &error); GET_UINT32(segment->subheader->numImageBands, &nBands, &error); GET_UINT32(segment->subheader->numMultispectralImageBands, &xBands, &error); nBands += xBands; GET_UINT32(segment->subheader->numRows, &nRows, &error); GET_UINT32(segment->subheader->numCols, &nColumns, &error); rowSize = nColumns * NITF_NBPP_TO_BYTES(nBits); /* Allocate buffers */ user = (nitf_Uint8 **)malloc(8 * nBands); assert(user); for (band = 0; band < nBands; band++) { user[band] = (nitf_Uint8*)malloc(rowSize); assert(user[band]); } /* setup for write */ nitf_ImageIO_writeSequential(segment->imageIO, output_io, &error); /* loop over the rows */ for (row = 0; row < nRows; ++row) { imgSrcTmp = imgSrc; /* set the band pointer */ for (band = 0; band < nBands; ++band) { bandSrc = nitf_ImageSource_getBand(imgSrcTmp, band, &error); if (bandSrc == NULL) return(0); (*(bandSrc->iface->read))(bandSrc->data, (char*)user[band], (size_t) rowSize, &error); } /* write the row */ if (!nitf_ImageIO_writeRows(segment->imageIO, output_io, 1, user, &error)) { return(0); } } /* done writing */ if (!nitf_ImageIO_writeDone(segment->imageIO, output_io, &error)) { return(0); } free(user); return(1); CATCH_ERROR: return(0); /* Needed for the GET macros */ }
int main(int argc, char *argv[]) { nitf_ImageIO *nitf; /* The parent nitf_ImageIO object */ char errorBuf[NITF_MAX_EMESSAGE]; /* Error buffer */ nitf_Uint8 **user; /* User buffer list */ int padded; /* Pad pixel present flag */ nitf_IOHandle fileHandle; /* I/O handle for reads */ int ofd; /* File descriptor for writes */ FILE *vector; /* FILE for reading vectors */ test_nitf_ImageIOConstructArgs *newArgs;/* Arguments for new */ test_nitf_ImageIOReadArgs *readArgs; /* Arguments for read */ nitf_ImageSubheader *subheader; /* For constructor */ size_t subWindowSize; /* Sub-window pixel count */ nitf_SubWindow *subWindow; /* Argument for read */ nitf_DownSampler* downSampler; /* Down-sample object */ char *error; /* Error message return */ nitf_Error errorObjActual; /* Error object instance */ nitf_Error *errorObj; /* Error object (pointer) */ int i; errorObj = &errorObjActual; /* Usage */ if (argc < 2) { fprintf(stderr, "Usage: %s imageVector readVector band0Out band1Out ... >result\n", argv[0]); exit(0); } /* Read image and read parameters from first and second arguments */ vector = fopen(argv[1], "r"); if (vector == NULL) { fprintf(stderr, "Error opening image vector file %s\n", argv[0]); exit(-1); } newArgs = test_nitf_ImageIOReadConstructArgs(vector, &error); if (newArgs == NULL) { fprintf(stderr, "%s\n", error); exit(-1); } fclose(vector); vector = fopen(argv[2], "r"); if (vector == NULL) { fprintf(stderr, "Error opening read vector file %s\n", argv[0]); exit(-1); } readArgs = test_nitf_ImageIOReadReadArgs(vector, &error); if (readArgs == NULL) { fprintf(stderr, "%s\n", error); exit(-1); } fclose(vector); /* Allocate user buffers */ subWindowSize = (readArgs->nRows) * (readArgs->nColumns) * (newArgs->nBits / 8); user = (nitf_Uint8 **) malloc(sizeof(nitf_Uint8 *) * (readArgs->nBands)); if (user == NULL) { fprintf(stderr, "Error allocating user buffer\n"); exit(-1); } for (i = 0;i < readArgs->nBands;i++) { user[i] = (nitf_Uint8 *) malloc(subWindowSize); if (user[i] == NULL) { fprintf(stderr, "Error allocating user buffer\n"); exit(-1); } } /* Create a fake image subheader to give to ImageIO constructor */ subheader = test_nitf_ImageIO_fakeSubheader(newArgs, &error); if (subheader == NULL) { fprintf(stderr, "%s", error); exit(-1); } /* Create the ImageIO */ nitf = nitf_ImageIO_construct(subheader, newArgs->offset, 0,/*length, must be correct for decompression */ NULL, NULL, errorObj); if (nitf == NULL) { fprintf(stderr, "NtfBlk new failed: %s\n", errorBuf); fprintf(stderr, "Err: %s\n", errorObj->message); exit(0); } nitf_ImageIO_setPadPixel(nitf, newArgs->padValue, NITF_NBPP_TO_BYTES(newArgs->nBits)); nitf_ImageIO_print(nitf, stdout); /* Open input file */ fileHandle = nitf_IOHandle_create(readArgs->name, NITF_ACCESS_READONLY, 0, errorObj); if (NITF_INVALID_HANDLE(fileHandle)) { nitf_Error_init(errorObj, "File open failed", NITF_CTXT, NITF_ERR_OPENING_FILE); nitf_Error_print(errorObj, stderr, "File open failed"); exit(0); } /* Setup for read (create and initialize sub-window object */ if ((subWindow = nitf_SubWindow_construct(errorObj)) == NULL) { nitf_Error_init(errorObj, "Sub-window object construct failed", NITF_CTXT, NITF_ERR_INVALID_OBJECT); nitf_Error_print(errorObj, stderr, "Sub-window object construct failed"); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); exit(0); } subWindow->startRow = readArgs->row; subWindow->numRows = readArgs->nRows; subWindow->startCol = readArgs->column; subWindow->numCols = readArgs->nColumns; subWindow->bandList = readArgs->bands; subWindow->numBands = readArgs->nBands; if ((readArgs->rowSkip != 1) || (readArgs->columnSkip != 1)) { if (strcmp(readArgs->downSample, "pixelSkip") == 0) { if ((downSampler = nitf_PixelSkip_construct( readArgs->rowSkip, readArgs->columnSkip, errorObj)) == NULL) { nitf_Error_init(errorObj, "Down-sampler object construct failed", NITF_CTXT, NITF_ERR_INVALID_OBJECT); nitf_Error_print(errorObj, stderr, "Down-sampler object construct failed"); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); nitf_SubWindow_destruct(&subWindow); exit(0); } if (nitf_SubWindow_setDownSampler( subWindow, downSampler, errorObj) == NITF_FAILURE) { nitf_Error_init(errorObj, "Read failed", NITF_CTXT, NITF_ERR_READING_FROM_FILE); nitf_Error_print(errorObj, stderr, "Read failed"); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); nitf_SubWindow_destruct(&subWindow); nitf_DownSampler_destruct(&downSampler); exit(0); } } else if (strcmp(readArgs->downSample, "max") == 0) { if ((downSampler = nitf_MaxDownSample_construct( readArgs->rowSkip, readArgs->columnSkip, errorObj)) == NULL) { nitf_Error_init(errorObj, "Down-sampler object construct failed", NITF_CTXT, NITF_ERR_INVALID_OBJECT); nitf_Error_print(errorObj, stderr, "Down-sampler object construct failed"); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); nitf_SubWindow_destruct(&subWindow); exit(0); } if (nitf_SubWindow_setDownSampler( subWindow, downSampler, errorObj) == NITF_FAILURE) { nitf_Error_init(errorObj, "Read failed", NITF_CTXT, NITF_ERR_READING_FROM_FILE); nitf_Error_print(errorObj, stderr, "Read failed"); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); nitf_SubWindow_destruct(&subWindow); nitf_DownSampler_destruct(&downSampler); exit(0); } } else if (strcmp(readArgs->downSample, "sumSq2") == 0) { if ((downSampler = nitf_SumSq2DownSample_construct( readArgs->rowSkip, readArgs->columnSkip, errorObj)) == NULL) { nitf_Error_init(errorObj, "Down-sampler object construct failed", NITF_CTXT, NITF_ERR_INVALID_OBJECT); nitf_Error_print(errorObj, stderr, "Down-sampler object construct failed"); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); nitf_SubWindow_destruct(&subWindow); exit(0); } if (nitf_SubWindow_setDownSampler( subWindow, downSampler, errorObj) == NITF_FAILURE) { nitf_Error_init(errorObj, "Read failed", NITF_CTXT, NITF_ERR_READING_FROM_FILE); nitf_Error_print(errorObj, stderr, "Read failed"); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); nitf_SubWindow_destruct(&subWindow); nitf_DownSampler_destruct(&downSampler); exit(0); } } else if (strcmp(readArgs->downSample, "select2") == 0) { if ((downSampler = nitf_Select2DownSample_construct( readArgs->rowSkip, readArgs->columnSkip, errorObj)) == NULL) { nitf_Error_init(errorObj, "Down-sampler object construct failed", NITF_CTXT, NITF_ERR_INVALID_OBJECT); nitf_Error_print(errorObj, stderr, "Down-sampler object construct failed"); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); nitf_SubWindow_destruct(&subWindow); exit(0); } if (nitf_SubWindow_setDownSampler( subWindow, downSampler, errorObj) == NITF_FAILURE) { nitf_Error_init(errorObj, "Read failed", NITF_CTXT, NITF_ERR_READING_FROM_FILE); nitf_Error_print(errorObj, stderr, "Read failed"); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); nitf_SubWindow_destruct(&subWindow); nitf_DownSampler_destruct(&downSampler); exit(0); } } else { nitf_Error_init(errorObj, "Invalid down-sample method", NITF_CTXT, NITF_ERR_INVALID_PARAMETER); nitf_Error_fprintf(errorObj, stderr, "Invalid down-sample method: %s\n", readArgs->downSample); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); nitf_SubWindow_destruct(&subWindow); exit(0); } } /* Read sub-window */ if (!nitf_ImageIO_read(nitf, fileHandle, subWindow, user, &padded, errorObj)) { nitf_Error_print(errorObj, stderr, "Read failed"); nitf_IOHandle_close(fileHandle); nitf_ImageIO_destruct(&nitf); nitf_SubWindow_destruct(&subWindow); exit(0); } nitf_SubWindow_destruct(&subWindow); nitf_IOHandle_close(fileHandle); printf("Padded = %d\n", padded); /* Write result */ for (i = 0;i < readArgs->nBands;i++) { if ((ofd = open(argv[3+i], O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) { fprintf(stderr, "Output file %d open failed\n", i); exit(0); } write(ofd, user[i], subWindowSize); close(ofd); } return 0; }
/* * Take a buffer of memory that we read out of a NITF segment * and write it one of two-ways. * * For non RGB 24-bit true-color data, write each band separately. * This demonstrates the typical, non-accelerated, generic read. * * For 24-bit true-color, if its band interleaved by pixel (mode 'P') * demonstrate accelerated mode, and read without de-interleaving pixels, * then write it to one big image as is. * */ void writeImage(nitf_ImageSegment * segment, char *imageName, nitf_ImageReader * deserializer, int imageNumber, nitf_Uint32 rowSkipFactor, nitf_Uint32 columnSkipFactor, NITF_BOOL optz, nitf_Error * error) { nitf_Uint32 nBits, nBands, xBands, nRows, nColumns; size_t subimageSize; nitf_SubWindow *subimage; unsigned int i; int padded; nitf_Uint8 **buffer = NULL; nitf_Uint32 band; nitf_Uint32 *bandList = NULL; nitf_DownSampler *pixelSkip; /* TODO, replace these macros! */ NITF_TRY_GET_UINT32(segment->subheader->numBitsPerPixel, &nBits, error); NITF_TRY_GET_UINT32(segment->subheader->numImageBands, &nBands, error); NITF_TRY_GET_UINT32(segment->subheader->numMultispectralImageBands, &xBands, error); nBands += xBands; NITF_TRY_GET_UINT32(segment->subheader->numRows, &nRows, error); NITF_TRY_GET_UINT32(segment->subheader->numCols, &nColumns, error); subimageSize = (nRows / rowSkipFactor) * (nColumns / columnSkipFactor) * NITF_NBPP_TO_BYTES(nBits); printf("Image number: %d\n", imageNumber); printf("NBANDS -> %d\n" "XBANDS -> %d\n" "NROWS -> %d\n" "NCOLS -> %d\n" "PVTYPE -> %.*s\n" "NBPP -> %.*s\n" "ABPP -> %.*s\n" "PJUST -> %.*s\n" "IMODE -> %.*s\n" "NBPR -> %.*s\n" "NBPC -> %.*s\n" "NPPBH -> %.*s\n" "NPPBV -> %.*s\n" "IC -> %.*s\n" "COMRAT -> %.*s\n", nBands, xBands, nRows, nColumns, (int)segment->subheader->pixelValueType->length, segment->subheader->pixelValueType->raw, (int)segment->subheader->numBitsPerPixel->length, segment->subheader->numBitsPerPixel->raw, (int)segment->subheader->actualBitsPerPixel->length, segment->subheader->actualBitsPerPixel->raw, (int)segment->subheader->pixelJustification->length, segment->subheader->pixelJustification->raw, (int)segment->subheader->imageMode->length, segment->subheader->imageMode->raw, (int)segment->subheader->numBlocksPerRow->length, segment->subheader->numBlocksPerRow->raw, (int)segment->subheader->numBlocksPerCol->length, segment->subheader->numBlocksPerCol->raw, (int)segment->subheader->numPixelsPerHorizBlock->length, segment->subheader->numPixelsPerHorizBlock->raw, (int)segment->subheader->numPixelsPerVertBlock->length, segment->subheader->numPixelsPerVertBlock->raw, (int)segment->subheader->imageCompression->length, segment->subheader->imageCompression->raw, (int)segment->subheader->compressionRate->length, segment->subheader->compressionRate->raw); if (optz) { /* * There is an accelerated mode for band-interleaved by pixel data. * In that case, we assume that the user doesnt want the data * de-interleaved into separate band buffers. To make this work * you have to tell us that you want only one band back, * and you have to provide us a singular buffer that is the * actual number of bands x the pixel size. Then we will * read the window and not de-interleave. * To demonstrate, for RGB24 images, let's we write out the 1 band * - this will be MUCH faster */ if (nBands == 3 && segment->subheader->imageMode->raw[0] == 'P' && strncmp("RGB", segment->subheader->imageRepresentation->raw, 3) == 0 && NITF_NBPP_TO_BYTES(nBits) == 1 && (strncmp("NC", segment->subheader->imageCompression->raw, 2) || strncmp("NM", segment->subheader->imageCompression->raw, 2))) { subimageSize *= nBands; nBands = 1; printf("Using accelerated 3-band RGB mode pix-interleaved image\n"); } if (nBands == 2 && segment->subheader->NITF_IMODE->raw[0] == 'P' && NITF_NBPP_TO_BYTES(nBits) == 4 && segment->subheader->bandInfo[0]->NITF_ISUBCAT->raw[0] == 'I' && (strncmp("NC", segment->subheader->NITF_IC->raw, 2) || strncmp("NM", segment->subheader->NITF_IC->raw, 2))) { subimageSize *= nBands; nBands = 1; printf("Using accelerated 2-band IQ mode pix-interleaved image\n"); } } subimage = nitf_SubWindow_construct(error); assert(subimage); /* * You need a buffer for each band (unless this is an * accelerated IQ complex or RGB read, in which case, you * can set the number of bands to 1, and size your buffer * accordingly to receive band-interleaved by pixel data) */ buffer = (nitf_Uint8 **) NITF_MALLOC(nBands * sizeof(nitf_Uint8*)); /* An iterator for bands */ band = 0; /* * This tells us what order to give you bands in. Normally * you just want it in the order of the banding. For example, * in a non-accelerated band-interleaved by pixel cases, you might * have a band of magnitude and a band of phase. If you order the * bandList backwards, the phase buffer comes first in the output */ bandList = (nitf_Uint32 *) NITF_MALLOC(sizeof(nitf_Uint32 *) * nBands); /* This example reads all rows and cols starting at 0, 0 */ subimage->startCol = 0; subimage->startRow = 0; /* Request rows is the full rows dividied by pixel skip (usually 1) */ subimage->numRows = nRows / rowSkipFactor; /* Request columns is the full columns divided by pixel skip (usually 1) */ subimage->numCols = nColumns / columnSkipFactor; /* Construct our pixel skip downsampler (does nothing if skips are 1) */ pixelSkip = nitf_PixelSkip_construct(rowSkipFactor, columnSkipFactor, error); if (!pixelSkip) { nitf_Error_print(error, stderr, "Pixel Skip construction failed"); goto CATCH_ERROR; } if (!nitf_SubWindow_setDownSampler(subimage, pixelSkip, error)) { nitf_Error_print(error, stderr, "Set down sampler failed"); goto CATCH_ERROR; } for (band = 0; band < nBands; band++) bandList[band] = band; subimage->bandList = bandList; subimage->numBands = nBands; assert(buffer); for (i = 0; i < nBands; i++) { buffer[i] = (nitf_Uint8 *) NITF_MALLOC(subimageSize); assert(buffer[i]); } if (!nitf_ImageReader_read (deserializer, subimage, buffer, &padded, error)) { nitf_Error_print(error, stderr, "Read failed"); goto CATCH_ERROR; } for (i = 0; i < nBands; i++) { nitf_IOHandle toFile; char file[NITF_MAX_PATH]; int pos; /* find end slash */ for (pos = strlen(imageName) - 1; pos && imageName[pos] != '\\' && imageName[pos] != '/'; pos--); pos = pos == 0 ? pos : pos + 1; NITF_SNPRINTF(file, NITF_MAX_PATH, "%s_%d__%d_%d_%d_band_%d", &imageName[pos], imageNumber, nRows / rowSkipFactor, nColumns / columnSkipFactor, nBits, i); /* remove decimals */ for (pos = strlen(file) - 1; pos; pos--) if (file[pos] == '.') file[pos] = '_'; strcat(file, ".out"); printf("File: %s\n", file); toFile = nitf_IOHandle_create(file, NITF_ACCESS_WRITEONLY, NITF_CREATE, error); if (NITF_INVALID_HANDLE(toFile)) { nitf_Error_print(error, stderr, "IO handle creation failed for raw band"); goto CATCH_ERROR; } if (!nitf_IOHandle_write(toFile, (const char *) buffer[i], subimageSize, error)) { nitf_Error_print(error, stderr, "IO handle write failed for raw band"); goto CATCH_ERROR; } nitf_IOHandle_close(toFile); } /* free buffers */ for (i = 0; i < nBands; i++) NITF_FREE(buffer[i]); NITF_FREE(buffer); NITF_FREE(bandList); nitf_SubWindow_destruct(&subimage); nitf_DownSampler_destruct(&pixelSkip); return; CATCH_ERROR: /* free buffers */ for (i = 0; i < nBands; i++) NITF_FREE(buffer[i]); NITF_FREE(buffer); NITF_FREE(bandList); printf("ERROR processing\n"); }
NITF_BOOL writeImage(nitf_ImageSegment* segment, nitf_IOHandle input_io, nitf_IOHandle output_io) { nitf_Error error; nitf_Off offset; int ret; nitf_ImageIO* ioClone; nitf_Uint8** buffer; nitf_Uint32 nBits, nBands, xBands, nRows, nColumns; nitf_SubWindow *subimage; size_t subimageSize; nitf_Uint32 band; nitf_Uint32 *bandList; NITF_BOOL success; int padded; nitf_ImageSource *imgSrc; /* Image source object */ nitf_BandSource *bandSrc; /* Current band source object */ /* clone the imageIO */ ioClone = nitf_ImageIO_clone(segment->imageIO, &error); if (!ioClone) { nitf_Error_print(&error, stderr, "Clone failed"); goto CATCH_ERROR; } /* get IO offset, and set the offset for the ImageIO */ offset = nitf_IOHandle_tell(output_io, &error); if (!NITF_IO_SUCCESS(offset)) goto CATCH_ERROR; if (!nitf_ImageIO_setFileOffset(segment->imageIO, offset, &error)) { goto CATCH_ERROR; } /* Read image */ GET_UINT32(segment->subheader->numBitsPerPixel, &nBits, &error); GET_UINT32(segment->subheader->numImageBands, &nBands, &error); GET_UINT32(segment->subheader->numMultispectralImageBands, &xBands, &error); nBands += xBands; GET_UINT32(segment->subheader->numRows, &nRows, &error); GET_UINT32(segment->subheader->numCols, &nColumns, &error); subimageSize = nRows * nColumns * NITF_NBPP_TO_BYTES(nBits); /* Allcoate buffers */ buffer = (nitf_Uint8 **)malloc(8 * nBands); assert(buffer); for (band = 0; band < nBands; band++) { buffer[band] = (nitf_Uint8*)malloc(subimageSize); assert(buffer[band]); } /* Set-up band array and subimage */ bandList = (nitf_Uint32 *)malloc(sizeof(nitf_Uint32 *) * nBands); subimage = nitf_SubWindow_construct(&error); assert(subimage); subimage->startCol = 0; subimage->startRow = 0; subimage->numRows = nRows; subimage->numCols = nColumns; for (band = 0; band < nBands; band++) { bandList[band] = band; } subimage->bandList = bandList; subimage->numBands = nBands; /* Read data */ if (!nitf_ImageIO_read(ioClone, input_io, subimage, buffer, &padded, &error) ) { nitf_Error_print(&error, stderr, "Read failed"); return(0); } free(bandList); /* Setup for image source */ imgSrc = nitf_ImageSource_construct(&error); if (imgSrc == NULL) return(0); for (band = 0; band < nBands; band++) { bandSrc = nitf_MemorySource_construct(buffer[band], (size_t) subimageSize, (nitf_Off) 0, NITF_NBPP_TO_BYTES(nBits), 0, &error); if (bandSrc == NULL) return(0); if (!nitf_ImageSource_addBand(imgSrc, bandSrc, &error)) return(0); } /* Do write */ ret = doWrite(segment, imgSrc, output_io, ioClone); if (ioClone) nitf_ImageIO_destruct(&ioClone); nitf_ImageSource_destruct(&imgSrc); /* OK return */ return ret; CATCH_ERROR: if (ioClone) nitf_ImageIO_destruct(&ioClone); printf("ERROR processing\n"); return 0; }
void manuallyWriteImageBands(nitf::ImageSegment & segment, const std::string& imageName, nitf::ImageReader& deserializer, int imageNumber) { int padded; nitf::ImageSubheader subheader = segment.getSubheader(); nitf::Uint32 nBits = subheader.getNumBitsPerPixel(); nitf::Uint32 nBands = subheader.getNumImageBands(); nitf::Uint32 xBands = subheader.getNumMultispectralImageBands(); nBands += xBands; nitf::Uint32 nRows = subheader.getNumRows(); nitf::Uint32 nColumns = subheader.getNumCols(); //one row at a time size_t subWindowSize = nColumns * NITF_NBPP_TO_BYTES(nBits); std::cout << "NBANDS -> " << nBands << std::endl << "XBANDS -> " << xBands << std::endl << "NROWS -> " << nRows << std::endl << "NCOLS -> " << nColumns << std::endl << "PVTYPE -> " << subheader.getPixelValueType().toString() << std::endl << "NBPP -> " << subheader.getNumBitsPerPixel().toString() << std::endl << "ABPP -> " << subheader.getActualBitsPerPixel().toString() << std::endl << "PJUST -> " << subheader.getPixelJustification().toString() << std::endl << "IMODE -> " << subheader.getImageMode().toString() << std::endl << "NBPR -> " << subheader.getNumBlocksPerRow().toString() << std::endl << "NBPC -> " << subheader.getNumBlocksPerCol().toString() << std::endl << "NPPBH -> " << (int)subheader.getNumPixelsPerHorizBlock() << std::endl << "NPPBV -> " << (int)subheader.getNumPixelsPerVertBlock() << std::endl << "IC -> " << subheader.getImageCompression().toString() << std::endl << "COMRAT -> " << subheader.getCompressionRate().toString() << std::endl; nitf::Uint8** buffer = new nitf::Uint8*[nBands]; nitf::Uint32* bandList = new nitf::Uint32[nBands]; for (nitf::Uint32 band = 0; band < nBands; band++) bandList[band] = band; nitf::SubWindow subWindow; subWindow.setStartCol(0); subWindow.setNumRows(1); subWindow.setNumCols(nColumns); // necessary ? nitf::DownSampler* pixelSkip = new nitf::PixelSkip(1, 1); subWindow.setDownSampler(pixelSkip); subWindow.setBandList(bandList); subWindow.setNumBands(nBands); assert(buffer); for (nitf::Uint32 i = 0; i < nBands; i++) { buffer[i] = new nitf::Uint8[subWindowSize]; assert(buffer[i]); } std::vector<nitf::IOHandle> handles; //make the files for (nitf::Uint32 i = 0; i < nBands; i++) { std::string name = makeBandName(imageName, imageNumber, i); nitf::IOHandle toFile(name, NITF_ACCESS_WRITEONLY, NITF_CREATE); handles.push_back(toFile); } //read all row blocks and write to disk for (nitf::Uint32 i = 0; i < nRows; ++i) { subWindow.setStartRow(i); deserializer.read(subWindow, buffer, &padded); for (nitf::Uint32 j = 0; j < nBands; j++) { handles[j].write((const char*)buffer[j], subWindowSize); } } //close output handles for (nitf::Uint32 i = 0; i < nBands; i++) handles[i].close(); /* free buffers */ for (nitf::Uint32 i = 0; i < nBands; i++) delete [] buffer[i]; delete [] buffer; delete [] bandList; delete pixelSkip; }
void manuallyWriteImageBands(nitf_ImageSegment * segment, const char *imageName, nitf_ImageReader * deserializer, int imageNumber, nitf_Error * error) { char *file; nitf_Uint32 nBits, nBands, xBands, nRows, nColumns; size_t subimageSize; nitf_SubWindow *subimage; unsigned int i; int padded; nitf_Uint8 **buffer = NULL; nitf_Uint32 band; nitf_Uint32 *bandList = NULL; NITF_TRY_GET_UINT32(segment->subheader->numBitsPerPixel, &nBits, error); NITF_TRY_GET_UINT32(segment->subheader->numImageBands, &nBands, error); NITF_TRY_GET_UINT32(segment->subheader->numMultispectralImageBands, &xBands, error); nBands += xBands; NITF_TRY_GET_UINT32(segment->subheader->numRows, &nRows, error); NITF_TRY_GET_UINT32(segment->subheader->numCols, &nColumns, error); subimageSize = nRows * nColumns * NITF_NBPP_TO_BYTES(nBits); printf("Image number: %d\n", imageNumber); printf("NBANDS -> %d\n" "XBANDS -> %d\n" "NROWS -> %d\n" "NCOLS -> %d\n" "PVTYPE -> %.*s\n" "NBPP -> %.*s\n" "ABPP -> %.*s\n" "PJUST -> %.*s\n" "IMODE -> %.*s\n" "NBPR -> %.*s\n" "NBPC -> %.*s\n" "NPPBH -> %.*s\n" "NPPBV -> %.*s\n" "IC -> %.*s\n" "COMRAT -> %.*s\n", nBands, xBands, nRows, nColumns, (int)segment->subheader->pixelValueType->length, segment->subheader->pixelValueType->raw, (int)segment->subheader->numBitsPerPixel->length, segment->subheader->numBitsPerPixel->raw, (int)segment->subheader->actualBitsPerPixel->length, segment->subheader->actualBitsPerPixel->raw, (int)segment->subheader->pixelJustification->length, segment->subheader->pixelJustification->raw, (int)segment->subheader->imageMode->length, segment->subheader->imageMode->raw, (int)segment->subheader->numBlocksPerRow->length, segment->subheader->numBlocksPerRow->raw, (int)segment->subheader->numBlocksPerCol->length, segment->subheader->numBlocksPerCol->raw, (int)segment->subheader->numPixelsPerHorizBlock->length, segment->subheader->numPixelsPerHorizBlock->raw, (int)segment->subheader->numPixelsPerVertBlock->length, segment->subheader->numPixelsPerVertBlock->raw, (int)segment->subheader->imageCompression->length, segment->subheader->imageCompression->raw, (int)segment->subheader->compressionRate->length, segment->subheader->compressionRate->raw); buffer = (nitf_Uint8 **) malloc(sizeof(nitf_Uint8*) * nBands); band = 0; bandList = (nitf_Uint32 *) malloc(sizeof(nitf_Uint32 *) * nBands); subimage = nitf_SubWindow_construct(error); assert(subimage); subimage->startCol = 0; subimage->startRow = 0; subimage->numRows = nRows; subimage->numCols = nColumns; for (band = 0; band < nBands; band++) bandList[band] = band; subimage->bandList = bandList; subimage->numBands = nBands; assert(buffer); for (i = 0; i < nBands; i++) { buffer[i] = (nitf_Uint8 *) malloc(subimageSize); assert(buffer[i]); } /* This should change to returning failures! */ /* if (! nitf_ImageIO_read(segment->imageIO, io, &subimage, buffer, &padded, error) ) { nitf_Error_print(error, stderr, "Read failed"); goto CATCH_ERROR; } */ if (!nitf_ImageReader_read (deserializer, subimage, buffer, &padded, error)) { nitf_Error_print(error, stderr, "Read failed"); goto CATCH_ERROR; } for (i = 0; i < nBands; i++) { nitf_IOHandle toFile; file = makeBandName(imageName, "img", imageNumber, i); toFile = nitf_IOHandle_create(file, NITF_ACCESS_WRITEONLY, NITF_CREATE, error); freeBandName(&file); if (NITF_INVALID_HANDLE(toFile)) { goto CATCH_ERROR; } if (!nitf_IOHandle_write(toFile, (const char *) buffer[i], subimageSize, error)) { goto CATCH_ERROR; } nitf_IOHandle_close(toFile); } /* free buffers */ for (i = 0; i < nBands; i++) { free(buffer[i]); } free(buffer); free(bandList); nitf_SubWindow_destruct(&subimage); return; CATCH_ERROR: /* free buffers */ for (i = 0; i < nBands; i++) { free(buffer[i]); } free(buffer); free(bandList); nitf_Error_print(error, stderr, "Manual write failed"); }
size_t ImageSubheader::getNumBytesPerPixel() const { const size_t numBitsPerPixel = nitf::Field(getNativeOrThrow()->numBitsPerPixel); return NITF_NBPP_TO_BYTES(numBitsPerPixel); }
int main(int argc, char *argv[]) { FILE *vector; /* File stream for input vector */ /* Arguments for new */ test_nitf_ImageIOConstructArgs *newArgs; /* Arguments for read */ test_nitf_ImageIOReadArgs *readArgs; char *errorStr; /* Error string */ nitf_ImageSubheader *subheader; /* Subheader for ImageIO constructor */ nitf_IOHandle io; /* Handle for output */ nitf_Error error; /* Error object */ nitf_ImageIO *image; /* ImageIO for image */ nitf_Uint8 *user[NUM_BANDS_MAX]; /* User buffer for write rows */ nitf_Uint8 ***data; /* Generated data [band][row][col] */ nitf_Uint32 band; /* Current band */ nitf_Uint32 row; /* Current row */ nitf_Uint32 col; /* Current column*/ if (argc < 3) { fprintf(stderr, "Not enough arguments\n"); exit(-1); } vector = fopen(argv[1], "r"); if (vector == NULL) { fprintf(stderr, "Error opening vector file %s\n", argv[1]); exit(-1); } newArgs = test_nitf_ImageIOReadConstructArgs(vector, &errorStr); if (newArgs == NULL) { fprintf(stderr, "%s\n", errorStr); return(-1); } fclose(vector); /* Create a fake image subheader to give to ImageIO constructor */ subheader = test_nitf_ImageIO_fakeSubheader(newArgs, &errorStr); if (subheader == NULL) { fprintf(stderr, "%s", error); return(-1); } /* Create Image */ if (strcmp(newArgs->dataPattern, "brcI4") == 0) { data = (nitf_Uint8 ***) test_nitf_ImageIO_brcI4(newArgs, &errorStr); if (data == NULL) { fprintf(stderr, "%s\n", errorStr); exit(-1); } } else if (strcmp(newArgs->dataPattern, "brcC8") == 0) { data = (nitf_Uint8 ***) test_nitf_ImageIO_brcC8(newArgs, &errorStr); if (data == NULL) { fprintf(stderr, "%s\n", errorStr); exit(-1); } } else { fprintf(stderr, "Invalid pattern method %s\n"); exit(-1); } /* Create output file */ io = nitf_IOHandle_create(argv[2], NITF_ACCESS_WRITEONLY, NITF_CREATE | NITF_TRUNCATE, &error); if (NITF_INVALID_HANDLE(io)) { nitf_Error_print(&error, stderr, "Error creating output file"); exit(1); } /* Create the ImageIO structure */ /* What about segment length in write ?? */ image = nitf_ImageIO_construct(subheader, 0, 0, NULL, NULL, &error); if (image == NULL) { nitf_Error_print(&error, stderr, "Error creating ImageIO"); exit(1); } /* Setup for write */ nitf_ImageIO_setPadPixel(image, newArgs->padValue, NITF_NBPP_TO_BYTES(newArgs->nBits)); if (nitf_ImageIO_writeSequential(image, io, &error) == 0) { nitf_Error_print(&error, stderr, "Error creating ImageIO"); exit(1); } /* Write rows */ for (row = 0;row < newArgs->nRows;row++) { for (band = 0;band < newArgs->nBands;band++) user[band] = (nitf_Uint8 *) & (data[band][row][0]); if (!nitf_ImageIO_writeRows(image, io, 1, user, &error)) { nitf_Error_print(&error, stderr, "Writing rows"); exit(1); } } if (!nitf_ImageIO_writeDone(image, io, &error)) { nitf_Error_print(&error, stderr, "Writing rows"); exit(1); } /* Destroy things */ test_nitf_ImageIO_freeArray(data); nitf_ImageIO_destruct(&image); nitf_IOHandle_close(io); exit(0); }
void writeImage(nitf::ImageSegment &segment, nitf::Reader &reader, const int imageNumber, const char *imageName, nitf_Uint32 rowSkipFactor, nitf_Uint32 columnSkipFactor, bool optz) { size_t subWindowSize; nitf::SubWindow subWindow; unsigned int i; int padded; nitf::Uint8** buffer = NULL; nitf::Uint32 band; nitf::Uint32 * bandList; nitf::ImageReader deserializer = reader.newImageReader(imageNumber); // missing skip factor nitf::ImageSubheader subheader = segment.getSubheader(); nitf::Uint32 nBits = subheader.getNumBitsPerPixel(); nitf::Uint32 nBands = subheader.getNumImageBands(); nitf::Uint32 xBands = subheader.getNumMultispectralImageBands(); nBands += xBands; nitf::Uint32 nRows = subheader.getNumRows(); nitf::Uint32 nCols = subheader.getNumCols(); subWindowSize = (size_t)(nRows / rowSkipFactor) * (size_t)(nCols / columnSkipFactor) * (size_t)NITF_NBPP_TO_BYTES(nBits); if (optz) { std::string irep = segment.getSubheader().getImageRepresentation().toString(); std::string ic = segment.getSubheader().getImageCompression().toString(); if (nBands == 3 && segment.getSubheader().getImageMode().toString() == "P" && str::startsWith(irep, "RGB") && NITF_NBPP_TO_BYTES(nBits) == 1 && str::startsWith(ic, "N")) { subWindowSize *= nBands; nBands = 1; std::cout << "Using accelerated 3-band RGB mode pix-interleaved image" << std::endl; } if (nBands == 2 && segment.getSubheader().getImageMode().toString() == "P" && str::startsWith(ic, "N")) { subWindowSize *= nBands; nBands = 1; std::cout << "Using accelerated 2-band IQ mode pix-interleaved image" << std::endl; } } std::cout << "NBANDS -> " << nBands << std::endl; std::cout << "XBANDS -> " << xBands << std::endl; std::cout << "NROWS -> " << nRows << std::endl; std::cout << "NCOLS -> " << nCols << std::endl; std::cout << "PVTYPE -> " << subheader.getPixelValueType().toString() << std::endl; std::cout << "NBPP -> " << subheader.getNumBitsPerPixel() .toString() << std::endl; std::cout << "ABPP -> " << subheader.getActualBitsPerPixel().toString() << std::endl; std::cout << "PJUST -> " << subheader.getPixelJustification().toString() << std::endl; std::cout << "IMODE -> " << subheader.getImageMode().toString() << std::endl; std::cout << "NBPR -> " << subheader.getNumBlocksPerRow().toString() << std::endl; std::cout << "NBPC -> " << subheader.getNumBlocksPerCol().toString() << std::endl; std::cout << "NPPBH -> " << (int)subheader.getNumPixelsPerHorizBlock() << std::endl; std::cout << "NPPBV -> " << (int)subheader.getNumPixelsPerVertBlock() << std::endl; std::cout << "IC -> " << subheader.getImageCompression().toString() << std::endl; std::cout << "COMRAT -> " << subheader.getCompressionRate().toString() << std::endl; std::cout << "Allocating work buffer..." << std::endl; buffer = new nitf::Uint8*[nBands]; assert(buffer); band = 0; bandList = new nitf::Uint32[nBands]; subWindow.setStartCol(0); subWindow.setStartRow(0); subWindow.setNumRows(nRows / rowSkipFactor); subWindow.setNumCols(nCols / columnSkipFactor); nitf::PixelSkip pixelSkip(rowSkipFactor, columnSkipFactor); subWindow.setDownSampler(&pixelSkip); for (band = 0; band < nBands; band++) { bandList[band] = band; buffer[band] = new nitf::Uint8[subWindowSize]; assert(buffer[band]); } subWindow.setBandList(bandList); subWindow.setNumBands(nBands); std::cout << "Reading image..." << std::endl; deserializer.read(subWindow, buffer, &padded); std::cout << "Call completed!" << std::endl; std::cout << "Writing bands..." << std::endl; for (i = 0; i < nBands; i++) { std::cout << "Writing band # " << i << std::endl; std::string base = sys::Path::basename(imageName); size_t where = 0; while ((where = base.find(".")) != (size_t)std::string::npos) base.replace(where, 1, "_"); std::ostringstream file; file << base << "__" << imageNumber << "__" << nRows / rowSkipFactor << '_' << nCols / columnSkipFactor << '_' << nBits << "_band_" << i << ".out"; nitf::IOHandle toFile(file.str(), NITF_ACCESS_WRITEONLY, NITF_CREATE); toFile.write((const char *) buffer[i], subWindowSize); toFile.close(); std::cout << "Finished # " << i << std::endl; } for (band = 0; band < nBands; band++) delete [] buffer[band]; delete [] buffer; delete [] bandList; }