Невозможно загрузить и сохранить необработанные данные изображения с помощью DevIL (библиотека изображений разработчика) - PullRequest
0 голосов
/ 27 марта 2019

Я пытаюсь использовать библиотеку изображений разработчика (DevIL) для сохранения необработанного изображения в градациях серого в изображение PNG на диске.

Согласно этому посту . Похоже, что все, что нужно дьяволу, - это предоставить заголовок с некоторыми метаданными изображения и размером изображения. Однако при попытке загрузить изображение в его стек возникает ошибка IL_INVALID_PARAM.

#include <iostream>
#include <vector>
#include <assert.h>

// Include Devil
#include <IL/il.h>
#include <IL/ilu.h>

#define IMAGE_HEIGHT 16
#define IMAGE_WIDTH 16
#define IMAGE_DEPTH 1
#define BYTES_PER_PIXEL 1
#define NUM_PIXELS IMAGE_WIDTH*IMAGE_HEIGHT
#define HEADER_SIZE 13


// from: https://stackoverflow.com/questions/27609152/how-to-load-devil-image-from-raw-data
struct RawHeader {
    ILuint width;  // 32 bit unsigned integer
    ILuint height; // 32 bit unsigned integer
    ILuint depth;  // 32 bit unsigned integer
    ILubyte bpp;   // 8 bit unsigned {Bytes per pixel}
};

int main() {
    printf("running main\n");
    // initialize the loading and saving sub library
    ilInit();
    iluInit();

    // create and bind the image id (typically referred to as 'image name' in the docs)
    ILuint img_id;
    ilGenImages(1, &img_id);
    ilBindImage(img_id);

    // generate the image and header
    RawHeader header = RawHeader();
    header.width = IMAGE_WIDTH;
    header.height = IMAGE_HEIGHT;
    header.depth = IMAGE_DEPTH;
    header.bpp = BYTES_PER_PIXEL;

    // create the raw image data
    auto *raw = (uint8_t *)malloc(NUM_PIXELS + HEADER_SIZE);

    //copy the header into the load function is looking for: https://github.com/DentonW/DevIL/blob/master/DevIL/src-IL/src/il_raw.cpp#L71
    std::copy((uint8_t *)&header, (uint8_t *)&header + HEADER_SIZE, raw);


    // fill raw with a gradient test image
    uint8_t *pix_ptr = raw + HEADER_SIZE;
    ILubyte pix = 0;
    for(int i=0; i < NUM_PIXELS; i++){
        *pix_ptr = pix;
        pix_ptr++;
        pix++;
        if(pix >= IMAGE_WIDTH){
            pix = 0;
        }
    }


    /*
     * We should now be in the format DevIL expects?
     * that is a 13 byte header followed by the raw image data
     * https://stackoverflow.com/questions/27609152/how-to-load-devil-image-from-raw-data
     * https://github.com/DentonW/DevIL/blob/master/DevIL/src-IL/src/il_raw.cpp#L71
     *
     * According to the docs, IL_INVALID_PARAM should only be raised if lump == NULL
     * http://www-f9.ijs.si/~matevz/docs/DevIL/il/f00152.htm
     */

    // assure there are no errors before we run our test...
    ILenum err = ilGetError();
    printf("ERROR CODE BEFORE LOADING: %d - %s\n\n", err, iluErrorString(err) );

    // according to docs, we shouldn't be raising a IL_INVALID_PARAM error if this passes?
    assert(raw != nullptr);

    // Load the image into the Devil Stack
    if(!ilLoadL(IL_RAW, raw, NUM_PIXELS) ){
        //Print out the header if it fails
        auto *raw_header_ptr = (RawHeader *)raw;
        printf("HEIGHT: %u, WIDTH: %u, DEPTH: %u, BPP: %hhu\n",
               raw_header_ptr->height,
               raw_header_ptr->width,
               raw_header_ptr->depth,
               raw_header_ptr->bpp);

        // print out every pixel to make sure the gradient was loaded in correctly
        // should be "0 1 2 3 4 ..." for every row
        uint8_t *pix_idx = raw + HEADER_SIZE;
        for(int i=0; i < IMAGE_HEIGHT; i++ ){
            for(int j=0; j < IMAGE_WIDTH; j++){
                printf("%hhu ", *pix_idx);
                pix_idx++;
            }
            printf("\n");
        }

        err = ilGetError();
        printf("\nERROR CODE AFTER LOADING: %d - %s\n", err, iluErrorString(err) );
        printf("failed\n");
        return 1;
    }

    // save the image to disk
    ilSaveImage("~/test.png");
    ilDeleteImages(1, &img_id);
    return 0;
}

Я получаю следующее

running main
ERROR CODE BEFORE LOADING: 0 - no error

HEIGHT: 16, WIDTH: 16, DEPTH: 1, BPP: 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 

ERROR CODE AFTER LOADING: 1289 - invalid parameter
failed

Process finished with exit code 1

...