Hello everyone,
I am trying to read a raw image with libraw using the example in the API page " https://www.libraw.org/docs/API-overview.html"
I wrote the following code and get a -2 file reading error.
I was able to read the same raw image with Python (fromfile) specifying bit ordering to 'big'. What should I do to read to do this with libraw in C++?
#include <iostream>
#include "libraw/libraw.h"
#include "libraw/libraw.h"
int main(int argc, char **argv)
{
LibRaw iProcessor;
// Open the file and read the metadata
char *fname = (char *)"/home/santana/myraw.raw";
int isOK = iProcessor.open_file(fname);
std::cout << " is ok ? " << isOK << std::endl;
printf("Image size: %d x %d\n", iProcessor.imgdata.sizes.width, iProcessor.imgdata.sizes.height);
iProcessor.unpack();
// Convert from imgdata.rawdata to imgdata.image:
iProcessor.raw2image();
for (int i = 0; i < iProcessor.imgdata.sizes.iwidth * iProcessor.imgdata.sizes.iheight; i++)
{
printf("i=%d R=%d G=%d B=%d G2=%d\n", i, iProcessor.imgdata.image[i][0],
iProcessor.imgdata.image[i][1], iProcessor.imgdata.image[i][2],
iProcessor.imgdata.image[i][3]);
}
// Finally, let us free the image processor for work with the next image
iProcessor.recycle();
return EXIT_SUCCESS;
}output :
is ok ? -2
Image size: 0 x 0

-2 is: LIBRAW_FILE
-2 is: LIBRAW_FILE_UNSUPPORTED
If your 'raw' file is just a sensor dump without metadata consider using open_bayer() call
-- Alex Tutubalin @LibRaw LLC
open_bayer : bufferdouble of real values
Thank you Alex for your answer. I tried with open_bayer as I think the raw file has no metadata. With the code bellow I could see that readb as 1280000 values instead of 640000 for an image 800x8000. The final result with dcraw_process is not satisfactory. I wonder If and how I could retrieve the unpacked values and do the conversion myself.
FILE *in = fopen(fname, "rb"); fseek(in, 0, SEEK_END); unsigned fsz = ftell(in); unsigned char *buffer = (unsigned char *)malloc(fsz); if (!buffer) return 2; fseek(in, 0, SEEK_SET); unsigned readb = fread(buffer, 1, fsz, in); if (readb != fsz) return 3; std::cout << "readb" << readb << std::endl; LibRaw rp; rp.imgdata.params.output_tiff = 1; int ret = rp.open_bayer(buffer, fsz, 800, 800, 0, 0, 0, 0, 0, LIBRAW_OPENBAYER_BGGR, 0, 0, 0); if (ret != LIBRAW_SUCCESS) return 4; if ((ret = rp.unpack()) != LIBRAW_SUCCESS) printf("Unpack error: %d\n", ret); if ((ret = rp.dcraw_process()) != LIBRAW_SUCCESS) printf("Processing error: %d\n", ret); char outfn[256]; sprintf(outfn, "%s.tif", fname); if (LIBRAW_SUCCESS != (ret = rp.dcraw_ppm_tiff_writer(outfn))) printf("Cannot write %s: %s\n", outfn, libraw_strerror(ret)); else printf("Created %s\n", outfn); ret = rp.dcraw_process(); // Check for error using LIBRAW_SUCCESS. I never get an error here ret = rp.dcraw_ppm_tiff_writer(fname);santana
If your input data is 16 bit
If your input data is 16 bit (2 bytes per pixel), 1,280,000 bytes is expected....
-- Alex Tutubalin @LibRaw LLC
Also, if your file is 2 bytes
Also, if your file is 2 bytes per pixel, uncompressed, you do not need LibRaw to read source data values. Your values are already here (in unsigned short format, probably you may need big/little-endian swap; I know nothing about your images and your camera)
-- Alex Tutubalin @LibRaw LLC
swapt little endian to big endian
Thank you again for your answers.
Actually, yes the data is encoded in int16.
I was able to read it in python swap bit ordering to bi endian. Any idea how I can achieve this in c++ ?
Also my guess for taking 2 bites with go for two consecutive bytes. Does this seam reasonable. I don' have all format specifications in hand.
santana
For byte swapping use
For byte swapping use something like ntohs() (actually this converts from big endian to your machine/host endianness, so it might be a noop if your machine is big endian as well) or, depending on your system/compiler, some incarnation of the bswap16() intrinsic/bultin function (e.g. __builtin_bswap16() for GCC, _byteswap_ushort() for MSVC, etc.)
__builtin_bswap16() did great
Thank you all for the answers. I read the binary with native C++ fstream (800x800 = 640000 values). then used __builtin_bswap16() to swap and obtain my bayer data which I was able to convert to RGB,
Many thanks
santana
procflags of open_bayer()
procflags of open_bayer() should also do the swap for you in the above example: https://www.libraw.org/docs/API-CXX.html#open_bayer