libjpeg库使用

libjpeg库是专门用于jpeg图片格式解压和压缩的库

程序实例如下:

#include <stdio.h>
#include <setjmp.h>
#include <string.h>
#include <stdlib.h>
#include "jpeg-lib/include/jpeglib.h"

#define PUT_2B(array,offset,value)  \
        (array[offset] = (char) ((value) & 0xFF), \
         array[offset+1] = (char) (((value) >> 8) & 0xFF))
#define PUT_4B(array,offset,value)  \
        (array[offset] = (char) ((value) & 0xFF), \
         array[offset+1] = (char) (((value) >> 8) & 0xFF), \
         array[offset+2] = (char) (((value) >> 16) & 0xFF), \
         array[offset+3] = (char) (((value) >> 24) & 0xFF))

void write_bmp_header(j_decompress_ptr cinfo, FILE *output_file)
{
        char bmpfileheader[14];
        char bmpinfoheader[40];
        long headersize, bfSize;
        int bits_per_pixel, cmap_entries;


        int step;

        /* Compute colormap size and total file size */
        if (cinfo->out_color_space == JCS_RGB) {
                if (cinfo->quantize_colors) {
                        /* Colormapped RGB */
                        bits_per_pixel = 8;
                        cmap_entries = 256;
                } else {
                        /* Unquantized, full color RGB */
                        bits_per_pixel = 24;
                        cmap_entries = 0;
                }
        } else {
                /* Grayscale output.  We need to fake a 256-entry colormap. */
                bits_per_pixel = 8;
                cmap_entries = 256;
        }

        step = cinfo->output_width * cinfo->output_components;

        while ((step & 3) != 0) step++;

        /* File size */
        headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */

        bfSize = headersize + (long) step * (long) cinfo->output_height;

        /* Set unused fields of header to 0 */
        memset(bmpfileheader, 0, sizeof(bmpfileheader));
        memset(bmpinfoheader, 0 ,sizeof(bmpinfoheader));

        /* Fill the file header */
        bmpfileheader[0] = 0x42;/* first 2 bytes are ASCII 'B', 'M' */
        bmpfileheader[1] = 0x4D;
        PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */
        /* we leave bfReserved1 & bfReserved2 = 0 */
        PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */

        /* Fill the info header (Microsoft calls this a BITMAPINFOHEADER) */
        PUT_2B(bmpinfoheader, 0, 40);   /* biSize */
        PUT_4B(bmpinfoheader, 4, cinfo->output_width); /* biWidth */
        PUT_4B(bmpinfoheader, 8, cinfo->output_height); /* biHeight */
        PUT_2B(bmpinfoheader, 12, 1);   /* biPlanes - must be 1 */
        PUT_2B(bmpinfoheader, 14, bits_per_pixel); /* biBitCount */
        /* we leave biCompression = 0, for none */
        /* we leave biSizeImage = 0; this is correct for uncompressed data */
        if (cinfo->density_unit == 2) { /* if have density in dots/cm, then */
                PUT_4B(bmpinfoheader, 24, (INT32) (cinfo->X_density*100)); /* XPels/M */
                PUT_4B(bmpinfoheader, 28, (INT32) (cinfo->Y_density*100)); /* XPels/M */
        }
        PUT_2B(bmpinfoheader, 32, cmap_entries); /* biClrUsed */
        /* we leave biClrImportant = 0 */

        if (fwrite(bmpfileheader, 1, 14, output_file) != (size_t) 14) {
                printf("write bmpfileheader error\n");
        }
        if (fwrite(bmpinfoheader, 1, 40, output_file) != (size_t) 40) {
                printf("write bmpinfoheader error\n");
        }

        if (cmap_entries > 0) {
        }
}

void write_pixel_data(j_decompress_ptr cinfo, unsigned char *output_buffer, FILE *output_file)
{
        int rows, cols;
        int row_width;
        int step;
        unsigned char *tmp = NULL;

        unsigned char *pdata;

        row_width = cinfo->output_width * cinfo->output_components;
        step = row_width;
        while ((step & 3) != 0) step++;

        pdata = (unsigned char *)malloc(step);
        memset(pdata, 0, step);

        tmp = output_buffer + row_width * (cinfo->output_height - 1);
        for (rows = 0; rows < cinfo->output_height; rows++) {
                for (cols = 0; cols < row_width; cols += 3) {
                        pdata[cols + 2] = tmp[cols + 0];
                        pdata[cols + 1] = tmp[cols + 1];
                        pdata[cols + 0] = tmp[cols + 2];
                }
                tmp -= row_width;
                fwrite(pdata, 1, step, output_file);
        }

        free(pdata);
}

int read_jpeg_file(const char *input_filename, const char *output_filename)
{
        struct jpeg_decompress_struct cinfo;
        struct jpeg_error_mgr jerr;
        FILE *input_file;
        FILE *output_file;
        JSAMPARRAY buffer;
        int row_width;

        unsigned char *output_buffer;
        unsigned char *tmp = NULL;

        cinfo.err = jpeg_std_error(&jerr);

        if ((input_file = fopen(input_filename, "rb")) == NULL) {
                fprintf(stderr, "can't open %s\n", input_filename);
                return -1;
        }

        if ((output_file = fopen(output_filename, "wb")) == NULL) {

                fprintf(stderr, "can't open %s\n", output_filename);
                return -1;
        }

        jpeg_create_decompress(&cinfo);

        /* Specify data source for decompression */
        jpeg_stdio_src(&cinfo, input_file);

        /* Read file header, set default decompression parameters */
        (void) jpeg_read_header(&cinfo, TRUE);

        /* Start decompressor */
        (void) jpeg_start_decompress(&cinfo);

        row_width = cinfo.output_width * cinfo.output_components;

        buffer = (*cinfo.mem->alloc_sarray)
                ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_width, 1);

        write_bmp_header(&cinfo, output_file);

        output_buffer = (unsigned char *)malloc(row_width * cinfo.output_height);
        memset(output_buffer, 0, row_width * cinfo.output_height);
        tmp = output_buffer;

        /* Process data */
        while (cinfo.output_scanline < cinfo.output_height) {
                (void) jpeg_read_scanlines(&cinfo, buffer, 1);

                memcpy(tmp, *buffer, row_width);
                tmp += row_width;
        }

        write_pixel_data(&cinfo, output_buffer, output_file);

        free(output_buffer);

        (void) jpeg_finish_decompress(&cinfo);

        jpeg_destroy_decompress(&cinfo);

        /* Close files, if we opened them */
        fclose(input_file);
        fclose(output_file);


        return 0;
}

int main(int argc, char *argv[])
{
        if (argc < 3) {
                read_jpeg_file("tt.jpg", "tt.bmp");
        } else {
                read_jpeg_file(argv[1], argv[2]);
        }
        return 0;
}
                                                                            

程序主要实现将一个jpeg格式文件转换成bmp格式文件,主要参考了libjpeg库中的example.c和djpeg.c

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
libjpeg是一种用C语言编写的 JPEG 图像压缩与解压缩,它提供了一些函数用于压缩和解压缩 JPEG 图像。在使用 libjpeg 之前,需要先安装 libjpeg 安装方法: 在 Linux 中,可以使用以下命令安装 libjpeg : sudo apt-get install libjpeg-dev 在 Windows 中,可以从官网下载 libjpeg 并进行安装使用方法: 1. 引入头文件 在需要使用 libjpeg 的源文件中,需要包含以下头文件: #include <stdio.h> #include <stdlib.h> #include <jpeglib.h> 2. 定义结构体 使用 libjpeg 时需要定义一些结构体,例如: struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; 3. 初始化压缩器或解压器 在使用压缩或解压功能之前,需要分别初始化压缩器或解压器,例如: // 初始化压缩器 jpeg_create_compress(&cinfo); // 初始化解压器 jpeg_create_decompress(&cinfo); 4. 设置参数 在使用压缩或解压功能之前,需要设置一些参数,例如: // 设置压缩图像的宽度和高度 cinfo.image_width = width; cinfo.image_height = height; // 设置颜色空间 cinfo.in_color_space = JCS_RGB; // 设置压缩品质 jpeg_set_quality(&cinfo, quality, TRUE); 5. 执行压缩或解压 设置完参数之后,可以执行压缩或解压操作,例如: // 执行压缩 jpeg_start_compress(&cinfo, TRUE); jpeg_write_scanlines(&cinfo, buffer, height); jpeg_finish_compress(&cinfo); // 执行解压 jpeg_start_decompress(&cinfo); jpeg_read_scanlines(&cinfo, buffer, height); jpeg_finish_decompress(&cinfo); 6. 销毁结构体 使用完压缩或解压功能后,需要销毁相应的结构体,例如: // 销毁压缩器 jpeg_destroy_compress(&cinfo); // 销毁解压器 jpeg_destroy_decompress(&cinfo); 以上是 libjpeg 的基本使用方法,具体可以参考官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值