Example #1
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;
}
Example #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);
}
Example #3
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");
}