Using WebP API to read and write WebP files

249 views
Skip to first unread message

kar.de...@gmail.com

unread,
Dec 7, 2018, 4:17:04 AM12/7/18
to WebP Discussion
Hi,

I am trying to read PNG image data into a WebP file with Lossless compression and also read the image data back from the stored WebP file.

I am able to read write the file but it seems that it is lossy rather than lossless.

Below is the code for the same.

I have used WebPEncodeLosslessRGBA to encode the image data and WebPDecode for decoding it back.
The for loop below it is to compare the decoded data with the input data from cv::Mat img.

PS:
Config and Pic is for WebPEncode() which did not work well for me either.


void ReadWrite(cv::Mat img, std::string fileName)
 {
   // Setup a config, starting form a preset and tuning some additional
   // parameters
   WebPConfig config;
   if (!WebPConfigInit(&config))
   {
    return;   // version error
   }
   // Setup the input data
   WebPPicture pic;
   if (!WebPPictureInit(&pic)) {
    return;  // version error
   }
   // Set up a byte-output write method. WebPMemoryWriter, for instance.
   WebPMemoryWriter wrt;
   WebPMemoryWriterInit(&wrt);     // initialize 'wrt'
   pic.user_data = (void*)&fileName;
   pic.writer = WebPWriterFunction1;
   pic.custom_ptr = (&wrt);
   pic.width = (int)img.cols;
   pic.height = (int)img.rows;
   //pic.argb_stride = (int)img.cols;
   //pic.use_argb = 1;
   config.lossless = 1;
   config.quality = 100;
  
  
   WebPConfigLosslessPreset(&config, 0);
  
   auto config_error = WebPValidateConfig(&config);  // not mandatory, but useful*/
  
   // allocated picture of dimension width x height
   if (!WebPPictureAlloc(&pic)) {
    return;   // memory error
   }
   // at this point, 'pic' has been initialized as a container,
   // and can receive the Y/U/V samples.
   // Alternatively, one could use ready-made import functions like
   // WebPPictureImportRGB(), which will take care of memory allocation.
   // In any case, past this point, one will have to call
   // WebPPictureFree(&pic) to reclaim memory.
   pic.y = img.data;
   //pic.argb = (uint32_t *)img.data;
  
   // Compress!
   uchar * output = nullptr;
   auto size = WebPEncodeLosslessRGBA(img.data, img.cols, img.rows, img.cols, &output); // pic.y);
   FILE *file = fopen(fileName.c_str(), "ab");
   if (!file) {
    std::cout << "Could not open JPEG file: " << strerror(errno);
   }
   if (fwrite(output, size, 1, file) < 1) {
    cerr << "Could not write JPEG file: " << strerror(errno);
   }
   fclose(file);
  
   //auto size = WebPEncode(&config, &pic);
  
   unsigned char* jpegBuf = nullptr;
   jpegBuf = new unsigned char[jpegSize];
   int WebPGetInfo(output, size, width, height);
   jpegBuf = output;
   WebPDecoderConfig config1;
   WebPInitDecoderConfig(&config1);
   WebPGetFeatures(jpegBuf, size, &config1.input);
   config1.output.colorspace = MODE_RGBA;
   config1.options.bypass_filtering = 1;
   config1.input.has_alpha = 1;
   config1.output.u.RGBA.size = size;
   config1.output.u.RGBA.stride = img.cols;
   config1.options.use_threads = 1;
   WebPDecode(jpegBuf, size, &config1);
   for (int n = 0; n < img.rows*img.cols; ++n)
   {
    if (img.data[n] != config1.output.u.RGBA.rgba[n])
    {
  std::cout << "Failed\n";
    }
   }
  
   WebPPictureFree(&pic);  // must be called independently of the 'ok' result.
   // output data should have been handled by the writer at that point.
   // -> compressed data is the memory buffer described by wrt.mem / wrt.size
   // deallocate the memory used by compressed data
   WebPMemoryWriterClear(&wrt);
 }
 

Pascal Massimino

unread,
Dec 7, 2018, 8:00:55 AM12/7/18
to WebP Discussion
Hi,

you should use RGBA input and convert from img.data[] to pic.argb[]
The erroneous lines are:


^^^^ here

   config.lossless = 1;
   config.quality = 100;
  
  
   WebPConfigLosslessPreset(&config, 0);
  
   auto config_error = WebPValidateConfig(&config);  // not mandatory, but useful*/
  
   // allocated picture of dimension width x height
   if (!WebPPictureAlloc(&pic)) {
    return;   // memory error
   }
   // at this point, 'pic' has been initialized as a container,
   // and can receive the Y/U/V samples.
   // Alternatively, one could use ready-made import functions like
   // WebPPictureImportRGB(), which will take care of memory allocation.
   // In any case, past this point, one will have to call
   // WebPPictureFree(&pic) to reclaim memory.
   pic.y = img.data;

^^^^ and especially here.

Also: pay special attention to ARGB vs BGRA vs RGBA vs...
and make sure CV is storing A,R,G,B samples in the order you want.

hope it helps,
skal/

 
--
You received this message because you are subscribed to the Google Groups "WebP Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to webp-discuss...@webmproject.org.
To post to this group, send email to webp-d...@webmproject.org.
Visit this group at https://groups.google.com/a/webmproject.org/group/webp-discuss/.
For more options, visit https://groups.google.com/a/webmproject.org/d/optout.
Reply all
Reply to author
Forward
0 new messages