Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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 */
}
Esempio n. 4
0
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;
}
Esempio n. 5
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");
}
Esempio n. 6
0
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
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");


}
Esempio n. 9
0
size_t ImageSubheader::getNumBytesPerPixel() const
{
    const size_t numBitsPerPixel =
            nitf::Field(getNativeOrThrow()->numBitsPerPixel);
    return NITF_NBPP_TO_BYTES(numBitsPerPixel);
}
Esempio n. 10
0
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);
}
Esempio n. 11
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;
}