Jpeglib代码提供乱码输出,甚至是捆绑的示例代码?

时间:2023-01-21 21:18:54

I'm on Ubuntu Intrepid and I'm using jpeglib62 6b-14. I was working on some code, which only gave a black screen with some garbled output at the top when I tried to run it. After a few hours of debugging I got it down to pretty much the JPEG base, so I took the example code, wrote a little piece of code around it and the output was exactly the same.

我在Ubuntu Intrepid,我正在使用jpeglib62 6b-14。我正在研究一些代码,当我试图运行它时,它只在顶部显示了一些带有乱码输出的黑屏。经过几个小时的调试后,我把它归结为几乎JPEG基础,所以我拿了示例代码,在它周围写了一小段代码,输出完全一样。

I'm convinced jpeglib is used in a lot more places on this system and it's simply the version from the repositories so I'm hesitant to say that this is a bug in jpeglib or the Ubuntu packaging.

我确信jpeglib在这个系统上的更多地方使用,它只是来自存储库的版本所以我很犹豫地说这是jpeglib或Ubuntu包装中的错误。

I put the example code below (most comments stripped). The input JPEG file is an uncompressed 640x480 file with 3 channels, so it should be 921600 bytes (and it is). The output image is JFIF and around 9000 bytes.

我把下面的示例代码(大多数评论都删除了)。输入的JPEG文件是一个带有3个通道的未压缩的640x480文件,所以它应该是921600字节(它是)。输出图像是JFIF,大约9000字节。

If you could help me with even a hint, I'd be very grateful.

如果你能帮我提一下,我会非常感激。

Thanks!

#include <stdio.h>
#include <stdlib.h>
#include "jpeglib.h"
#include <setjmp.h>

int main ()
{
  // read data
  FILE *input = fopen("input.jpg", "rb");
  JSAMPLE *image_buffer = (JSAMPLE*) malloc(sizeof(JSAMPLE) * 640 * 480 * 3);
  if(input == NULL or image_buffer == NULL)
    exit(1);
  fread(image_buffer, 640 * 3, 480, input);

  // initialise jpeg library
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);

  // write to foo.jpg
  FILE *outfile = fopen("foo.jpg", "wb");
  if (outfile == NULL)
    exit(1);
  jpeg_stdio_dest(&cinfo, outfile);

  // setup library
  cinfo.image_width = 640;
  cinfo.image_height = 480;
  cinfo.input_components = 3; // 3 components (R, G, B)
  cinfo.in_color_space = JCS_RGB; // RGB
  jpeg_set_defaults(&cinfo); // set defaults

  // start compressing
  int row_stride = 640 * 3; // number of characters in a row
  JSAMPROW row_pointer[1]; // pointer to the current row data
  jpeg_start_compress(&cinfo, TRUE); // start compressing to jpeg

  while (cinfo.next_scanline < cinfo.image_height) {
    row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
  }

  jpeg_finish_compress(&cinfo);

  // clean up
  fclose(outfile);
  jpeg_destroy_compress(&cinfo);
}

3 个解决方案

#1


2  

You're reading a JPEG file into memory (without decompressing it) and writing out that buffer as if it were uncompressed, that's why you're getting garbage. You need to decompress the image first before you can feed it into the JPEG compressor.

你正在将JPEG文件读入内存(不解压缩)并将该缓冲区写出来,就好像它是未压缩的那样,这就是你得到垃圾的原因。在将图像输入JPEG压缩器之前,需要首先解压缩图像。

In other words, the JPEG compressor assumes that its input is raw pixels.

换句话说,JPEG压缩器假设其输入是原始像素。

You can convert your input image into raw RGB using ImageMagick:

您可以使用ImageMagick将输入图像转换为原始RGB:

convert input.jpg rgb:input.raw

It should be exactly 921600 bytes in size.

它的大小应该是921600字节。

EDIT: Your question is misleading when you state that your input JPEG file in uncompressed. Anyway, I compiled your code and it works fine, compresses the image correctly. If you can upload the file you're using as input, it might be possible to debug further. If not, I suggest you test your program using an image created from a known JPEG using ImageMagick:

编辑:当您声明您的输入JPEG文件未压缩时,您的问题会产生误导。无论如何,我编译了你的代码,它工作正常,正确压缩图像。如果您可以上传您正在使用的文件作为输入,则可以进一步调试。如果没有,我建议您使用ImageMagick使用已知JPEG创建的图像测试您的程序:

convert some_image_that_is_really_a_jpg.jpg -resize 640x480! rgb:input.jpg

#2


1  

You are reading the input file into memmory compressed and then you are recompressing it before righting to file. You need to decompress the image_buffer before compressing it again. Or alternativly instead of reading in a jpeg read a .raw image

您正在将输入文件读入压缩的memmory,然后在正确归档到文件之前将其重新压缩。您需要在再次压缩之前解压缩image_buffer。或者替代阅读jpeg而不是阅读.raw图像

#3


1  

What exactly do you mean by "The input JPEG file is an uncompressed"? Jpegs are all compressed.

“输入的JPEG文件是未压缩的”是什么意思? Jpegs都是压缩的。

In your code, it seems that in the loop you give one row of pixels to libjpeg and ask it to compress it. It doesn't work that way. libjpeg has to have at least 8 rows to start compression (sometimes even more, depending on parameters). So it's best to leave libjpeg to control the input buffer and don't do its job for it.

在你的代码中,似乎在循环中你给libjpeg一行像素并要求它压缩它。它不起作用。 libjpeg必须至少有8行才能开始压缩(有时甚至更多,具体取决于参数)。所以最好让libjpeg控制输入缓冲区而不是为它做任务。

I suggest you read how cjpeg.c does its job. The easiest way I think is to put your data in a raw type known by libjpeg (say, BMP), and use libjpeg to read the BMP image into its internal representation and compress from there.

我建议你阅读cjpeg.c如何完成它的工作。我认为最简单的方法是将数据放入libjpeg(比如BMP)已知的原始类型中,并使用libjpeg将BMP图像读入其内部表示并从那里进行压缩。

#1


2  

You're reading a JPEG file into memory (without decompressing it) and writing out that buffer as if it were uncompressed, that's why you're getting garbage. You need to decompress the image first before you can feed it into the JPEG compressor.

你正在将JPEG文件读入内存(不解压缩)并将该缓冲区写出来,就好像它是未压缩的那样,这就是你得到垃圾的原因。在将图像输入JPEG压缩器之前,需要首先解压缩图像。

In other words, the JPEG compressor assumes that its input is raw pixels.

换句话说,JPEG压缩器假设其输入是原始像素。

You can convert your input image into raw RGB using ImageMagick:

您可以使用ImageMagick将输入图像转换为原始RGB:

convert input.jpg rgb:input.raw

It should be exactly 921600 bytes in size.

它的大小应该是921600字节。

EDIT: Your question is misleading when you state that your input JPEG file in uncompressed. Anyway, I compiled your code and it works fine, compresses the image correctly. If you can upload the file you're using as input, it might be possible to debug further. If not, I suggest you test your program using an image created from a known JPEG using ImageMagick:

编辑:当您声明您的输入JPEG文件未压缩时,您的问题会产生误导。无论如何,我编译了你的代码,它工作正常,正确压缩图像。如果您可以上传您正在使用的文件作为输入,则可以进一步调试。如果没有,我建议您使用ImageMagick使用已知JPEG创建的图像测试您的程序:

convert some_image_that_is_really_a_jpg.jpg -resize 640x480! rgb:input.jpg

#2


1  

You are reading the input file into memmory compressed and then you are recompressing it before righting to file. You need to decompress the image_buffer before compressing it again. Or alternativly instead of reading in a jpeg read a .raw image

您正在将输入文件读入压缩的memmory,然后在正确归档到文件之前将其重新压缩。您需要在再次压缩之前解压缩image_buffer。或者替代阅读jpeg而不是阅读.raw图像

#3


1  

What exactly do you mean by "The input JPEG file is an uncompressed"? Jpegs are all compressed.

“输入的JPEG文件是未压缩的”是什么意思? Jpegs都是压缩的。

In your code, it seems that in the loop you give one row of pixels to libjpeg and ask it to compress it. It doesn't work that way. libjpeg has to have at least 8 rows to start compression (sometimes even more, depending on parameters). So it's best to leave libjpeg to control the input buffer and don't do its job for it.

在你的代码中,似乎在循环中你给libjpeg一行像素并要求它压缩它。它不起作用。 libjpeg必须至少有8行才能开始压缩(有时甚至更多,具体取决于参数)。所以最好让libjpeg控制输入缓冲区而不是为它做任务。

I suggest you read how cjpeg.c does its job. The easiest way I think is to put your data in a raw type known by libjpeg (say, BMP), and use libjpeg to read the BMP image into its internal representation and compress from there.

我建议你阅读cjpeg.c如何完成它的工作。我认为最简单的方法是将数据放入libjpeg(比如BMP)已知的原始类型中,并使用libjpeg将BMP图像读入其内部表示并从那里进行压缩。