0

I am wrote a function with Jpeg Turbo to allow it to do compression and it looks something like this:

bool JPEGCompress::compress(const uint8_t* data, size_t width, size_t height, ImageFrame::image_type type, std::string& out)
{
  // Prealloc if not
  out.reserve(1 << 24); // Preallocate 16 MB output buffer

  // Allocate memory for compressed output
  int subsamp = TJSAMP_420;
  auto outsize_max = tjBufSize(width, height, subsamp);
  if (size_t(-1) == outsize_max) {
    fmt::print("Size out of bounds: w={} h={} ss={}\n", width, height, subsamp);
    return false;
  }
  out.resize(outsize_max);

  // Select Pixel Format
  int pix_fmt = -1;
  if(type == ImageFrame::image_type::ImageColor)
    pix_fmt = TJPF_RGB;
  else if(type == ImageFrame::image_type::ImageGray) 
    pix_fmt = TJPF_GRAY;
  else{
    fmt::print("Compression doesn't work for this format: {}", ImageFrame::convEnum(type));
    return false;
  }

  // Compress
  auto outptr = (uint8_t*) out.data();
  auto outsize = outsize_max;
  if (-1 == tjCompress2(
        compressor_, data, width, 0, height, pix_fmt,
        &outptr, &outsize, subsamp, quality_, TJFLAG_NOREALLOC)) {
    fmt::print("Error encoding image: {}\n", tjGetErrorStr2(compressor_));
    return false;
  }
  out.resize(outsize);

  return true;
}

It works great with RGB images, but fails on greyscale images with Error encoding image: Unsupported color conversion request

I don't know what I am doing wrong with the library

raaj
  • 2,869
  • 4
  • 38
  • 58

1 Answers1

3

I recently had the same issue (with similar code that writes both RGB and grayscale images), and it took me a while to find the culprit:

The sub-sampling that is applied must match the color space: for actual color images, using any of the TJSAMP_4xx constants (e.g. TJSAMP_420) is a valid choice, but for grayscale images the sub-sampling must be set to TJSAMP_GRAY.

With that libjpeg-turbo will happily store grayscale JPEG files using the tjCompress2() API.

chris_se
  • 1,006
  • 1
  • 7