转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静 <xianjimli at hotmail dot com>
jpeg2rle发布
RLE(run-length encoding)是一个压缩算法,它最大的好处就是解压速度快。用来做嵌入式设备开机时的LOGO是不错的选择,android里也使用了这种格式。今天写了个小工具jpeg2rle,它把JPEG文件转换成RLE文件。
o 把一行数据写入RLE文件。
void put_scanline_to_file (FILE * outfile, char *scanline, int width, int row_stride) { int i = 0; char *pixels = scanline; char *start = scanline; while (i < width) { unsigned short n = 0; for (; i < width; i++, n++) { if (memcmp (pixels, pixels + 3 * n, 3) != 0) { break; } } unsigned char r = pixels[0]; unsigned char g = pixels[1]; unsigned char b = pixels[2]; unsigned short rle565 = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); fwrite (&n, 2, 1, outfile); fwrite (&rle565, 2, 1, outfile); pixels += 3 * n; } return; }
o 解压jpeg
int jpeg2rle (char *filename, char *outfilename) { struct jpeg_decompress_struct cinfo; int i = 0; struct my_error_mgr jerr; FILE *infile; FILE *outfile; JSAMPARRAY buffer; int row_stride; if ((infile = fopen (filename, "rb")) == NULL) { fprintf (stderr, "can't open %s/n", filename); return 0; } if ((outfile = fopen (outfilename, "wb")) == NULL) { fprintf (stderr, "can't open %s/n", outfilename); fclose (infile); return 0; } cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp (jerr.setjmp_buffer)) { jpeg_destroy_decompress (&cinfo); fclose (infile); fclose (outfile); return 0; } jpeg_create_decompress (&cinfo); jpeg_stdio_src (&cinfo, infile); (void) jpeg_read_header (&cinfo, TRUE); (void) jpeg_start_decompress (&cinfo); row_stride = cinfo.output_width * cinfo.output_components; buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) & cinfo, JPOOL_IMAGE, row_stride, 1); printf("size: %dx%d/n", cinfo.output_width, cinfo.output_height); while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines (&cinfo, buffer, 1); put_scanline_to_file (outfile, buffer[0], cinfo.output_width, row_stride); } (void) jpeg_finish_decompress (&cinfo); jpeg_destroy_decompress (&cinfo); fclose (infile); fclose (outfile); return 1; }
o 主函数
int main (int argc, char *argv[]) { if (argc != 3) { printf ("usage: %s jpeg rle/n", argv[0]); } else { jpeg2rle(argv[1], argv[2]); } return 0; }
有兴趣朋友到这里下载。