root / trunk / code / projects / colonet / server / vision / memdst.c @ 1428
History | View | Annotate | Download (3.1 KB)
1 | 936 | rcahoon | /*
|
---|---|---|---|
2 | * Code taken from http://www.codeguru.com/forum/archive/index.php/t-378333.html
|
||
3 | * by 'clown'
|
||
4 | */
|
||
5 | |||
6 | #include <stdio.h> |
||
7 | #include "jpeglib.h" |
||
8 | #include "memdst.h" |
||
9 | |||
10 | /*
|
||
11 | This a custom destination manager for jpeglib that
|
||
12 | enables the use of memory to memory compression.
|
||
13 | |||
14 | See IJG documentation for details.
|
||
15 | */
|
||
16 | typedef struct { |
||
17 | struct jpeg_destination_mgr pub; /* base class */ |
||
18 | JOCTET* buffer; /* buffer start address */
|
||
19 | int bufsize; /* size of buffer */ |
||
20 | size_t datasize; /* final size of compressed data */
|
||
21 | int* outsize; /* user pointer to datasize */ |
||
22 | int errcount; /* counts up write errors due to |
||
23 | buffer overruns */
|
||
24 | } memory_destination_mgr; |
||
25 | |||
26 | typedef memory_destination_mgr* mem_dest_ptr;
|
||
27 | |||
28 | /* ------------------------------------------------------------- */
|
||
29 | /* MEMORY DESTINATION INTERFACE METHODS */
|
||
30 | /* ------------------------------------------------------------- */
|
||
31 | |||
32 | |||
33 | /* This function is called by the library before any data gets written */
|
||
34 | METHODDEF(void)
|
||
35 | init_destination (j_compress_ptr cinfo) |
||
36 | { |
||
37 | mem_dest_ptr dest = (mem_dest_ptr)cinfo->dest; |
||
38 | |||
39 | dest->pub.next_output_byte = dest->buffer; /* set destination buffer */
|
||
40 | dest->pub.free_in_buffer = dest->bufsize; /* input buffer size */
|
||
41 | dest->datasize = 0; /* reset output size */ |
||
42 | dest->errcount = 0; /* reset error count */ |
||
43 | } |
||
44 | |||
45 | /* This function is called by the library if the buffer fills up
|
||
46 | |||
47 | I just reset destination pointer and buffer size here.
|
||
48 | Note that this behavior, while preventing seg faults
|
||
49 | will lead to invalid output streams as data is over-
|
||
50 | written.
|
||
51 | */
|
||
52 | METHODDEF(boolean) |
||
53 | empty_output_buffer (j_compress_ptr cinfo) |
||
54 | { |
||
55 | mem_dest_ptr dest = (mem_dest_ptr)cinfo->dest; |
||
56 | dest->pub.next_output_byte = dest->buffer; |
||
57 | dest->pub.free_in_buffer = dest->bufsize; |
||
58 | ++dest->errcount; /* need to increase error count */
|
||
59 | |||
60 | return TRUE;
|
||
61 | } |
||
62 | |||
63 | /* Usually the library wants to flush output here.
|
||
64 | |||
65 | I will calculate output buffer size here.
|
||
66 | Note that results become incorrect, once
|
||
67 | empty_output_buffer was called.
|
||
68 | This situation is notified by errcount.
|
||
69 | */
|
||
70 | METHODDEF(void)
|
||
71 | term_destination (j_compress_ptr cinfo) |
||
72 | { |
||
73 | mem_dest_ptr dest = (mem_dest_ptr)cinfo->dest; |
||
74 | dest->datasize = dest->bufsize - dest->pub.free_in_buffer; |
||
75 | if (dest->outsize)
|
||
76 | { |
||
77 | if (dest->errcount)
|
||
78 | *dest->outsize = -1;
|
||
79 | else
|
||
80 | *dest->outsize = (int)dest->datasize;
|
||
81 | } |
||
82 | } |
||
83 | |||
84 | /* Override the default destination manager initialization
|
||
85 | provided by jpeglib. Since we want to use memory-to-memory
|
||
86 | compression, we need to use our own destination manager.
|
||
87 | */
|
||
88 | GLOBAL(void)
|
||
89 | jpeg_memory_dest (j_compress_ptr cinfo, JOCTET* buffer, int bufsize, int* outsize) |
||
90 | { |
||
91 | mem_dest_ptr dest; |
||
92 | |||
93 | /* first call for this instance - need to setup */
|
||
94 | if (cinfo->dest == 0) { |
||
95 | cinfo->dest = (struct jpeg_destination_mgr *)
|
||
96 | (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, |
||
97 | sizeof (memory_destination_mgr));
|
||
98 | } |
||
99 | |||
100 | dest = (mem_dest_ptr) cinfo->dest; |
||
101 | dest->bufsize = bufsize; |
||
102 | dest->buffer = buffer; |
||
103 | dest->outsize = outsize; |
||
104 | /* set method callbacks */
|
||
105 | dest->pub.init_destination = init_destination; |
||
106 | dest->pub.empty_output_buffer = empty_output_buffer; |
||
107 | dest->pub.term_destination = term_destination; |
||
108 | } |