Search code examples
c++jpegimage-compressionlibjpeg

Read raw compressed buffer from file.jpg using jpeglib


I am looking to write a code to open a file.jpg and load the data into a buffer without actually decompressing the data. I need to send the data as is.

I have found a code that reads an image and decompresses it. I don't know how to modify the code to just get the raw bytes not decompressed version.

  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr jerr;
  FILE * infile;        /* source file */
  JSAMPARRAY buffer;        /* Output row buffer */
  int row_stride;       /* physical row width in output buffer */

  if ((infile = fopen(filename, "rb")) == NULL) {
    fprintf(stderr, "can't open %s\n", filename);
    return 0;
  }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress(&cinfo);

  /* Step 2: specify data source (eg, a file) */
  jpeg_stdio_src(&cinfo, infile);

  (void) jpeg_read_header(&cinfo, TRUE);

  // Here I want to only get raw bytes
  (void) jpeg_start_decompress(&cinfo);

  row_stride = cinfo.output_width * cinfo.output_components;
  /* Make a one-row-high sample array that will go away when done with image */
  buffer = (*cinfo.mem->alloc_sarray)
        ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

  while (cinfo.output_scanline < cinfo.output_height) {

    (void) jpeg_read_scanlines(&cinfo, buffer, 1);
    /* Assume put_scanline_someplace wants a pointer and sample count. */
    // put_scanline_someplace(buffer[0], row_stride);
  }

  /* Step 7: Finish decompression */

  (void) jpeg_finish_decompress(&cinfo);      

  jpeg_destroy_decompress(&cinfo);

  fclose(infile);

Solution

  • After exchanging comments below the question post, it turned out that if we don't care about decompression, simple byte reading would suffice. Here is the code that solved the problem:

    char* data = (char*)malloc(max_w*max_h*3 +100); 
    
    if (data == NULL) {
        printf("Input data must not be NULL.\n");
        return 0;
    }
    
    FILE *fp = fopen(filename, "rb"); /* b - binary mode */
    if (fp == NULL) {
        printf("Error opening file %s\n", filename);
        return 0;
    }
    
    struct stat filestatus;
    stat(filename, &filestatus);
    size_t data_size = filestatus.st_size;
    
    size_t len = fread(data, 1, data_size , fp);
    if (len != data_size) {
        printf("Error reading file %s\n", filename);
        return 0;
    }
    
    fclose(fp);
    return len;
    
    // free(data) when you are done.