Я пытаюсь использовать библиотеку изображений разработчика (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