/* * 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 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); }
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"); }