Guetzli压缩rgba文件为jpg格式(google新出的压缩图片算法)

源码和怎么安装使用guetzli查看文章www.ctrlqun.com/paper/paper_3.html。

闲话不说,直奔主题,执行 guetzli test.rgba out.jpg

报错:
Marker byte (0xff) expected, found: 0 pos=0 len=614400
Can't read jpg data from input file
Guetzli processing failed
不可行,不能直接进行压缩rgba格式文件,官方说纯像素的也可以,仔细看代码
压缩处理程序guetzli.cc,主要看压缩调用程序:
  //判断是不是png格式
  if (in_data.size() >= 8 &&
      memcmp(in_data.data(), kPNGMagicBytes, sizeof(kPNGMagicBytes)) == 0) {
    int xsize, ysize;
    std::vector rgb;
    if (!ReadPNG(fin, &xsize, &ysize, &rgb)) {
      fprintf(stderr, "Error reading PNG data from input file\n");
      return 1;
    }
    if (!guetzli::Process(params, &stats, rgb, xsize, ysize, &out_data)) {
      fprintf(stderr, "Guetzli processing failed\n");
      return 1;
    }
  } else {//其他格式
    if (!guetzli::Process(params, &stats, in_data, &out_data)) {
      fprintf(stderr, "Guetzli processing failed\n");
      return 1;
    }
  }


心想就是其他格式里,在

if (!ReadJpeg(data, JPEG_READ_ALL, &jpg)) {
    fprintf(stderr, "Can't read jpg data from input file\n");//报错位置
    return false;
  }


看到调用报错位置,即程序ReadJpeg出问题,继续进入ReadJpeg

bool ReadJpeg(const uint8_t* data, const size_t len, JpegReadMode mode,
              JPEGData* jpg) {
  size_t pos = 0;
  // Check SOI marker.
  EXPECT_MARKER();//报错位置
....


EXPECT_MARKER()程序:

#define EXPECT_MARKER() \
  if (pos + 2 > len || data[pos] != 0xff) {                             \
    fprintf(stderr, "Marker byte (0xff) expected, found: %d "           \
            "pos=%d len=%d\n",                                          \
            (pos < len ? data[pos] : 0), static_cast(pos),         \
            static_cast(len));                                     \
    jpg->error = JPEG_MARKER_BYTE_NOT_FOUND;                            \
    return false;                                                       \
  }


可以发现:这是判断该文件是不是jpg格式文件。所以返回最先处理判断的ifelse:
直接将我们的rgba文件先处理为rgb文件,

每四个数值取前面三个,然后放到rgb里面即可。

char  *screen_buf = (char *)malloc(PBUF_SIZE);//需要在main()之前进行定义#define PBUF_SIZE 614400
memset(screen_buf, 0, PBUF_SIZE);             //这里的PBUF_SIZE 为宽320 高480 的像素size大小 614400 = 320*480*4
for (int i = 0; i < (in_data.size()/4); i++) {//in_data为读取的文件内容
  memcpy(screen_buf+i*3, in_data.data()+i*4, 3);//每四个取三个
}
int sizeofbuf = 3*(in_data.size()/4);          //rgba转为rgb后的size大小

int xsize = 320, ysize = 480;//xsize为原始图片宽,ysize为原始图片高
std::vector rgb(screen_buf, screen_buf+sizeofbuf);//初始化rgb,含义是将screen_buf 初始位置之后sizeofbuf的内容给rgb


然后make 即可,执行 guetzli test.rgba out.jpg成功,需要花一点时间,因为这个压缩程序计算量很大。

你可能感兴趣的:(互联网,C语言)