2011-01-02 11 views
0

私はlibjpegを使ってjpegに画像を圧縮する方法を議論する別の質問を見つけました。動作するようになっている、このコードを、私を発見した:libjpegでoバッファを書くのにもう少し助けてください。

Compressing IplImage to JPEG using libjpeg in OpenCV

ここでは、コード(それはOKコンパイル)です:

/* 
This a custom destination manager for jpeglib that 
enables the use of memory to memory compression. 

See IJG documentation for details. 
*/ 
typedef struct { 
struct jpeg_destination_mgr pub; /* base class */ 
JOCTET* buffer; /* buffer start address */ 
int bufsize; /* size of buffer */ 
size_t datasize; /* final size of compressed data */ 
int* outsize; /* user pointer to datasize */ 
int errcount; /* counts up write errors due to 
buffer overruns */ 
} memory_destination_mgr; 

typedef memory_destination_mgr* mem_dest_ptr; 

/* ------------------------------------------------------------- */ 
/* MEMORY DESTINATION INTERFACE METHODS */ 
/* ------------------------------------------------------------- */ 


/* This function is called by the library before any data gets written */ 
METHODDEF(void) 
init_destination (j_compress_ptr cinfo) 
{ 
mem_dest_ptr dest = (mem_dest_ptr)cinfo->dest; 

dest->pub.next_output_byte = dest->buffer; /* set destination buffer */ 
dest->pub.free_in_buffer = dest->bufsize; /* input buffer size */ 
dest->datasize = 0; /* reset output size */ 
dest->errcount = 0; /* reset error count */ 
} 

/* This function is called by the library if the buffer fills up 

I just reset destination pointer and buffer size here. 
Note that this behavior, while preventing seg faults 
will lead to invalid output streams as data is over- 
written. 
*/ 
METHODDEF(boolean) 
empty_output_buffer (j_compress_ptr cinfo) 
{ 
mem_dest_ptr dest = (mem_dest_ptr)cinfo->dest; 
dest->pub.next_output_byte = dest->buffer; 
dest->pub.free_in_buffer = dest->bufsize; 
++dest->errcount; /* need to increase error count */ 

return TRUE; 
} 

/* Usually the library wants to flush output here. 

I will calculate output buffer size here. 
Note that results become incorrect, once 
empty_output_buffer was called. 
This situation is notified by errcount. 
*/ 
METHODDEF(void) 
term_destination (j_compress_ptr cinfo) 
{ 
mem_dest_ptr dest = (mem_dest_ptr)cinfo->dest; 
dest->datasize = dest->bufsize - dest->pub.free_in_buffer; 
if (dest->outsize) *dest->outsize += (int)dest->datasize; 
} 

/* Override the default destination manager initialization 
provided by jpeglib. Since we want to use memory-to-memory 
compression, we need to use our own destination manager. 
*/ 
GLOBAL(void) 
jpeg_memory_dest (j_compress_ptr cinfo, JOCTET* buffer, int bufsize, int* outsize) 
{ 
mem_dest_ptr dest; 

/* first call for this instance - need to setup */ 
if (cinfo->dest == 0) { 
cinfo->dest = (struct jpeg_destination_mgr *) 
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 
sizeof (memory_destination_mgr)); 
} 

dest = (mem_dest_ptr) cinfo->dest; 
dest->bufsize = bufsize; 
dest->buffer = buffer; 
dest->outsize = outsize; 
/* set method callbacks */ 
dest->pub.init_destination = init_destination; 
dest->pub.empty_output_buffer = empty_output_buffer; 
dest->pub.term_destination = term_destination; 
} 

/* ------------------------------------------------------------- */ 
/* MEMORY SOURCE INTERFACE METHODS */ 
/* ------------------------------------------------------------- */ 

/* Called before data is read */ 
METHODDEF(void) 
init_source (j_decompress_ptr dinfo) 
{ 
/* nothing to do here, really. I mean. I'm not lazy or something, but... 
we're actually through here. */ 
} 

/* Called if the decoder wants some bytes that we cannot provide... */ 
METHODDEF(boolean) 
fill_input_buffer (j_decompress_ptr dinfo) 
{ 
/* we can't do anything about this. This might happen if the provided 
buffer is either invalid with regards to its content or just a to 
small bufsize has been given. */ 

/* fail. */ 
return FALSE; 
} 

/* From IJG docs: "it's not clear that being smart is worth much trouble" 
So I save myself some trouble by ignoring this bit. 
*/ 
METHODDEF(void) 
skip_input_data (j_decompress_ptr dinfo, INT32 num_bytes) 
{ 
/* There might be more data to skip than available in buffer. 
This clearly is an error, so screw this mess. */ 
if ((size_t)num_bytes > dinfo->src->bytes_in_buffer) { 
dinfo->src->next_input_byte = 0; /* no buffer byte */ 
dinfo->src->bytes_in_buffer = 0; /* no input left */ 
} else { 
dinfo->src->next_input_byte += num_bytes; 
dinfo->src->bytes_in_buffer -= num_bytes; 
} 
} 

/* Finished with decompression */ 
METHODDEF(void) 
term_source (j_decompress_ptr dinfo) 
{ 
/* Again. Absolute laziness. Nothing to do here. Boring. */ 
} 

GLOBAL(void) 
jpeg_memory_src (j_decompress_ptr dinfo, unsigned char* buffer, size_t size) 
{ 
struct jpeg_source_mgr* src; 

/* first call for this instance - need to setup */ 
if (dinfo->src == 0) { 
dinfo->src = (struct jpeg_source_mgr *) 
(*dinfo->mem->alloc_small) ((j_common_ptr) dinfo, JPOOL_PERMANENT, 
sizeof (struct jpeg_source_mgr)); 
} 

src = dinfo->src; 
src->next_input_byte = buffer; 
src->bytes_in_buffer = size; 
src->init_source = init_source; 
src->fill_input_buffer = fill_input_buffer; 
src->skip_input_data = skip_input_data; 
src->term_source = term_source; 
/* IJG recommend to use their function - as I don't know **** 
about how to do better, I follow this recommendation */ 
src->resync_to_restart = jpeg_resync_to_restart; 
} 

は私がする必要があるのは、これで私のプログラムでjpeg_stdio_destを交換ですコード:

int numBytes = 0; //size of jpeg after compression 
char * storage = new char[150000]; //storage buffer 
JOCTET *jpgbuff = (JOCTET*)storage; //JOCTET pointer to buffer 
jpeg_memory_dest(&cinfo,jpgbuff,150000,&numBytes); 

だから、私は今の代わりにメモリのファイルに動作しますが、書き込みをこの関数に上記の4本のラインを組み込むためにいくつかの助けが必要:

int write_jpeg_file(char *filename) 
{ 
    struct jpeg_compress_struct cinfo; 
    struct jpeg_error_mgr jerr; 

    /* this is a pointer to one row of image data */ 
    JSAMPROW row_pointer[1]; 
    FILE *outfile = fopen(filename, "wb"); 

    if (!outfile) 
    { 
     printf("Error opening output jpeg file %s\n!", filename); 
     return -1; 
    } 
    cinfo.err = jpeg_std_error(&jerr); 
    jpeg_create_compress(&cinfo); 
    jpeg_stdio_dest(&cinfo, outfile); 

    /* Setting the parameters of the output file here */ 
    cinfo.image_width = width; 
    cinfo.image_height = height; 
    cinfo.input_components = bytes_per_pixel; 
    cinfo.in_color_space = color_space; 
    /* default compression parameters, we shouldn't be worried about these */ 
    jpeg_set_defaults(&cinfo); 
    /* Now do the compression .. */ 
    jpeg_start_compress(&cinfo, TRUE); 
    /* like reading a file, this time write one row at a time */ 
    while(cinfo.next_scanline < cinfo.image_height) 
    { 
     row_pointer[0] = &raw_image[ cinfo.next_scanline * cinfo.image_width * cinfo.input_components]; 
     jpeg_write_scanlines(&cinfo, row_pointer, 1); 
    } 
    /* similar to read file, clean up after we're done compressing */ 
    jpeg_finish_compress(&cinfo); 
    jpeg_destroy_compress(&cinfo); 
    fclose(outfile); 
    /* success code is 1! */ 
    return 1; 
} 

誰も私にそれを少し助けることができましたか?私はそれに干渉してみましたが、それをどうやって行うのか分かりません。私はこの行を次のように置き換えます:

jpeg_stdio_dest(&cinfo, outfile); 

これはうまくいかないでしょう。その機能で少し変更する必要があるものがあり、私はそれらのポインタとメモリ管理から少し失われています。 jpeg_memory_destため

答えて

1

プロトタイプは次のとおりです。4つの引数を持つ(3つの引数が期待されている)

jpeg_memory_dest(&cinfo,jpgbuff,150000,&numBytes); 

GLOBAL(void) 
jpeg_memory_dest(j_compress_ptr cinfo, JOCTET *buffer,int bufsize) 

あなたはとしてそれを呼んでいます。 cinfoのタイプはstruct jpeg_compress_structですが、予想されるタイプはj_compress_ptr

ですかこれはあなたが得ようとしているのか、それともこのエラーですか?これを修正してからもう一度試してみてください。

+0

私は既にVirtualBoxを閉じました。私は明日もう一度お試しになり、うまくいかなければエラーも投稿します。 –

関連する問題