使用libjpeg(jpeg-6b)库在内存中转换jpeg文件(不修改源代码)

 最近在做一个linux下的服务,ubuntu系统。服务涉及到了生成jpeg(不过不是生成文件,是生成内存块,直接发送给客户端使用),在网上查了查,找到了 libjpeg 库,使用了一下,不错,不过libjpeg是直接生成文件的。 然后就在网上找在内存中使用的办法,结果n多的帖子都是要修改源代码,我个人认为做为一个大名鼎鼎在类库不应该这样变态,肯定有对应的办法。

 

最终总算在google group里找到了方法。

源帖如下:http://groups.google.com/group/openjpeg/browse_thread/thread/331e6cf60f70797f/e3c5b46797986c04?pli=1

 

The following is code to convert an openjpeg opj_image_t to jpeg using
libjpeg (jpeg-6b). Currently it supports RGB and compression only but
augmenting that should be fairly straightforward.

The jpeg error interface has been overridden so as not to issue an
immediate exit() on error - as has the destination manager (it writes
to memory rather than a stdio stream as libjpeg offers by default).
This is why all the callbacks are present.


Just pass a char **, size_t *, and opj_image_t * to imagetojpeg()
which will allocate space for jpeg output and set the passed buf
and sz to the allocated space and size thereof respectively. Caller
is responsible for free()ing.


-cl


--
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openjpeg.h>
#include <jpeglib.h>


/* Override my own error checking functions */
#define ec_malloc malloc
#define ec_calloc calloc
#define ec_realloc realloc


struct imagetojpeg_err {
        struct jpeg_error_mgr jerr;
        int ret;

 

};


static void imagetojpeg_err_exit(j_common_ptr cinfo)
{
        struct imagetojpeg_err *err = (void *)cinfo->err;

        err->ret = -1;


        return;

 

}


static void imagetojpeg_err_output(j_common_ptr cinfo)
{
        (void) cinfo;
        return;


}


static void imagetojpeg_err_emit(j_common_ptr cinfo, int level)
{
        (void) cinfo, (void) level;
        return;


}


static void imagetojpeg_err_format(j_common_ptr cinfo, char *buf)
{
        (void) cinfo, (void) buf;
        return;


}


static void imagetojpeg_err_reset(j_common_ptr cinfo)
{
        (void) cinfo;
        return;


}


static void imagetojpeg_err_set(j_compress_ptr cinfo, struct
imagetojpeg_err *err)
{
        memset(err, 0, sizeof *err);
        err->jerr.error_exit = imagetojpeg_err_exit;
        err->jerr.emit_message = imagetojpeg_err_emit;
        err->jerr.output_message = imagetojpeg_err_output;
        err->jerr.format_message = imagetojpeg_err_format;
        err->jerr.reset_error_mgr = imagetojpeg_err_reset;
        cinfo->err = (void *)err;

        return;

 

}


struct imagetojpeg_dst {
        struct jpeg_destination_mgr jdst;
        JOCTET *buf;
        JOCTET *off;
        size_t sz;
        size_t used;


};


static void imagetojpeg_dst_init(j_compress_ptr cinfo)
{
        struct imagetojpeg_dst *dst = (void *)cinfo->dest;

        dst->used = 0;
        dst->sz = cinfo->image_width
                * cinfo->image_height
                * cinfo->input_components / 8;  /* 1/8th of raw size
*/
        dst->buf = ec_malloc(dst->sz * sizeof *dst->buf);
        dst->off = dst->buf;
        dst->jdst.next_output_byte = dst->off;
        dst->jdst.free_in_buffer = dst->sz;


        return;

 

}


static boolean imagetojpeg_dst_empty(j_compress_ptr cinfo)
{
        struct imagetojpeg_dst *dst = (void *)cinfo->dest;

        dst->sz *= 2;
        dst->used = dst->off - dst->buf;
        dst->buf = ec_realloc(dst->buf, dst->sz * sizeof *dst->buf);
        dst->off = dst->buf + dst->used;
        dst->jdst.next_output_byte = dst->off;
        dst->jdst.free_in_buffer = dst->sz - dst->used;


        return TRUE;

 

}


static void imagetojpeg_dst_term(j_compress_ptr cinfo)
{
        struct imagetojpeg_dst *dst = (void *)cinfo->dest;

        dst->used += dst->sz - dst->jdst.free_in_buffer;
        dst->off = dst->buf + dst->used;


        return;

 

}


static void imagetojpeg_dst_set(j_compress_ptr cinfo, struct
imagetojpeg_dst *dst)
{
        dst->jdst.init_destination = imagetojpeg_dst_init;
        dst->jdst.empty_output_buffer = imagetojpeg_dst_empty;
        dst->jdst.term_destination = imagetojpeg_dst_term;
        cinfo->dest = (void *)dst;

        return;

 

}


static int imagetojpeg(char **buf, size_t *szo, opj_image_t *img)
{
        size_t w = img->x1 - img->x0;
        size_t h = img->y1 - img->y0;
        size_t i, c, nc = img->numcomps;
        uint8_t *rgbt, *rgbp;
        struct jpeg_compress_struct cinfo;
        struct imagetojpeg_err err;
        struct imagetojpeg_dst dst;
        JSAMPROW *rows;

        /* this order should not be changed */
        imagetojpeg_err_set(&cinfo, &err);
        jpeg_create_compress(&cinfo);
        if (err.ret != 0)
                return -1;
        imagetojpeg_dst_set(&cinfo, &dst);
        cinfo.image_width = w;
        cinfo.image_height = h;
        cinfo.input_components = nc;
        cinfo.in_color_space = JCS_RGB;
        jpeg_set_defaults(&cinfo);
        jpeg_start_compress(&cinfo, TRUE);
        if (err.ret != 0) {
                jpeg_destroy_compress(&cinfo);
                return -1;
        }


        /*
         * src:
         * component 0: rrr ...
         * component 1: ggg ...
         * component 2: bbb ...
         *
         * dst:
         * rgbp = rgbrgbrgbrgb ...
         */


        rgbt = rgbp = ec_malloc(w * h * nc);
        for (i = 0; i < w * h; i++) {
                for (c = 0; c < nc; c++)
                        *rgbp++ = img->comps[c].data[i];
        }
        rows = ec_malloc(h * sizeof *rows);
        for (i = 0; i < h; i++)
                rows[i] = &rgbt[i * w * nc];


        if (jpeg_write_scanlines(&cinfo, rows, h) == h && err.ret == 0)
                jpeg_finish_compress(&cinfo);
        jpeg_destroy_compress(&cinfo);
        free(rows);
        free(rgbt);


        *buf = (char *)dst.buf;
        *szo = dst.used;


        return err.ret;


}

 


今天转过来,希望对大家有帮助。

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值