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

发布于 2024-07-13 02:06:58 字数 1853 浏览 5 评论 0原文

我使用的是 Ubuntu Intrepid,并且使用的是 jpeglib62 6b-14。 我正在编写一些代码,当我尝试运行它时,它只给出了黑屏,顶部有一些乱码输出。 经过几个小时的调试后,我几乎得到了 JPEG 基础,因此我采用了示例代码,围绕它编写了一小段代码,输出完全相同。

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

我将示例代码放在下面(删除了大部分注释)。 输入 JPEG 文件是一个未压缩的 640x480 文件,具有 3 个通道,因此它应该是 921600 字节(确实如此)。输出图像是 JFIF,大约 9000 字节。

如果您能帮助我,哪怕是一点提示,我都会非常感激。

谢谢!

#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);
}

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.

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.

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.

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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦里南柯 2024-07-20 02:06:59

您正在将输入文件读入压缩内存,然后在恢复文件之前重新压缩它。 您需要先解压缩 image_buffer,然后才能再次压缩它。 或者也可以不读取 jpeg 而是读取 .raw 图像

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

等风来 2024-07-20 02:06:59

“输入的 JPEG 文件是未压缩的”到底是什么意思? Jpeg 均经过压缩。

在您的代码中,似乎在循环中您将一行像素提供给 libjpeg 并要求它对其进行压缩。 事实并非如此。 libjpeg 必须至少有 8 行才能开始压缩(有时甚至更多,具体取决于参数)。 因此,最好让 libjpeg 来控制输入缓冲区,而不是为其完成其工作。

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

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

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.

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.

久而酒知 2024-07-20 02:06:58

您将 JPEG 文件读入内存(不解压缩)并写出该缓冲区,就好像它未压缩一样,这就是您收到垃圾的原因。 您需要先解压缩图像,然后才能将其输入 JPEG 压缩器。

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

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

convert input.jpg rgb:input.raw

它的大小应该正好是 921600 字节。

编辑:当您声明输入JPEG文件为未压缩时,您的问题具有误导性。 不管怎样,我编译了你的代码,它工作正常,正确压缩图像。 如果您可以上传用作输入的文件,则可能可以进一步调试。 如果没有,我建议您使用 ImageMagick 从已知 JPEG 创建的图像来测试您的程序:

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

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.

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

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

convert input.jpg rgb:input.raw

It should be exactly 921600 bytes in size.

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:

convert some_image_that_is_really_a_jpg.jpg -resize 640x480! rgb:input.jpg
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文