forked from tjko/jpegoptim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
jpegdest.c
114 lines (78 loc) · 2.68 KB
/
jpegdest.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
* jpegdest.c
*
* Copyright (C) 2014 Timo Kokkonen
* All Rights Reserved.
*
* custom libjpeg "Destination Manager" for saving into RAM
*
* $Id$
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jpeglib.h>
#include <jerror.h>
#include "jpegoptim.h"
/* custom jpeg destination manager object */
typedef struct {
struct jpeg_destination_mgr pub; /* public fields */
unsigned char **buf_ptr;
size_t *bufsize_ptr;
size_t incsize;
unsigned char *buf;
size_t bufsize;
} jpeg_memory_destination_mgr;
typedef jpeg_memory_destination_mgr* jpeg_memory_destination_ptr;
void jpeg_memory_init_destination (j_compress_ptr cinfo)
{
jpeg_memory_destination_ptr dest = (jpeg_memory_destination_ptr) cinfo->dest;
dest->pub.next_output_byte = dest->buf;
dest->pub.free_in_buffer = dest->bufsize;
}
boolean jpeg_memory_empty_output_buffer (j_compress_ptr cinfo)
{
jpeg_memory_destination_ptr dest = (jpeg_memory_destination_ptr) cinfo->dest;
unsigned char *newbuf;
/* abort if incsize is 0 (no expansion of buffer allowed) */
if (dest->incsize == 0) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 42);
/* otherwise, try expanding buffer... */
newbuf = realloc(dest->buf,dest->bufsize + dest->incsize);
if (!newbuf) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 42);
dest->pub.next_output_byte = newbuf + dest->bufsize;
dest->pub.free_in_buffer = dest->incsize;
dest->buf = newbuf;
dest->bufsize += dest->incsize;
dest->incsize *= 2;
return TRUE;
}
void jpeg_memory_term_destination (j_compress_ptr cinfo)
{
jpeg_memory_destination_ptr dest = (jpeg_memory_destination_ptr) cinfo->dest;
*dest->buf_ptr = dest->buf;
*dest->bufsize_ptr = dest->bufsize - dest->pub.free_in_buffer;
}
void jpeg_memory_dest (j_compress_ptr cinfo, unsigned char **bufptr, size_t *bufsizeptr, size_t incsize)
{
jpeg_memory_destination_ptr dest;
if (!cinfo || !bufptr || !bufsizeptr)
fatal("invalid call to jpeg_memory_dest()");
if (!*bufptr || *bufsizeptr == 0)
fatal("invalid buffer passed to jpeg_memory_dest()");
/* allocate destination manager object for compress object, if needed */
if (!cinfo->dest) {
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ( (j_common_ptr) cinfo,
JPOOL_PERMANENT,
sizeof(jpeg_memory_destination_mgr) );
}
dest = (jpeg_memory_destination_ptr)cinfo->dest;
dest->buf_ptr = bufptr;
dest->buf = *bufptr;
dest->bufsize_ptr = bufsizeptr;
dest->bufsize = *bufsizeptr;
dest->incsize = incsize;
dest->pub.init_destination = jpeg_memory_init_destination;
dest->pub.empty_output_buffer = jpeg_memory_empty_output_buffer;
dest->pub.term_destination = jpeg_memory_term_destination;
}