1 | /* |
2 | * The copyright in this software is being made available under the 2-clauses |
3 | * BSD License, included below. This software may be subject to other third |
4 | * party and contributor rights, including patent rights, and no such rights |
5 | * are granted under this license. |
6 | * |
7 | * Copyright (c) 2005, Herve Drolon, FreeImage Team |
8 | * All rights reserved. |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' |
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | |
32 | #include "opj_includes.h" |
33 | |
34 | opj_image_t* opj_image_create0(void) |
35 | { |
36 | opj_image_t *image = (opj_image_t*)opj_calloc(1, sizeof(opj_image_t)); |
37 | return image; |
38 | } |
39 | |
40 | opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts, |
41 | opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) |
42 | { |
43 | OPJ_UINT32 compno; |
44 | opj_image_t *image = NULL; |
45 | |
46 | image = (opj_image_t*) opj_calloc(1, sizeof(opj_image_t)); |
47 | if (image) { |
48 | image->color_space = clrspc; |
49 | image->numcomps = numcmpts; |
50 | /* allocate memory for the per-component information */ |
51 | image->comps = (opj_image_comp_t*)opj_calloc(1, |
52 | image->numcomps * sizeof(opj_image_comp_t)); |
53 | if (!image->comps) { |
54 | /* TODO replace with event manager, breaks API */ |
55 | /* fprintf(stderr,"Unable to allocate memory for image.\n"); */ |
56 | opj_image_destroy(image); |
57 | return NULL; |
58 | } |
59 | /* create the individual image components */ |
60 | for (compno = 0; compno < numcmpts; compno++) { |
61 | opj_image_comp_t *comp = &image->comps[compno]; |
62 | comp->dx = cmptparms[compno].dx; |
63 | comp->dy = cmptparms[compno].dy; |
64 | comp->w = cmptparms[compno].w; |
65 | comp->h = cmptparms[compno].h; |
66 | comp->x0 = cmptparms[compno].x0; |
67 | comp->y0 = cmptparms[compno].y0; |
68 | comp->prec = cmptparms[compno].prec; |
69 | comp->bpp = cmptparms[compno].bpp; |
70 | comp->sgnd = cmptparms[compno].sgnd; |
71 | if (comp->h != 0 && |
72 | (OPJ_SIZE_T)comp->w > SIZE_MAX / comp->h / sizeof(OPJ_INT32)) { |
73 | /* TODO event manager */ |
74 | opj_image_destroy(image); |
75 | return NULL; |
76 | } |
77 | comp->data = (OPJ_INT32*) opj_image_data_alloc( |
78 | (size_t)comp->w * comp->h * sizeof(OPJ_INT32)); |
79 | if (!comp->data) { |
80 | /* TODO replace with event manager, breaks API */ |
81 | /* fprintf(stderr,"Unable to allocate memory for image.\n"); */ |
82 | opj_image_destroy(image); |
83 | return NULL; |
84 | } |
85 | memset(comp->data, 0, (size_t)comp->w * comp->h * sizeof(OPJ_INT32)); |
86 | } |
87 | } |
88 | |
89 | return image; |
90 | } |
91 | |
92 | void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) |
93 | { |
94 | if (image) { |
95 | if (image->comps) { |
96 | OPJ_UINT32 compno; |
97 | |
98 | /* image components */ |
99 | for (compno = 0; compno < image->numcomps; compno++) { |
100 | opj_image_comp_t *image_comp = &(image->comps[compno]); |
101 | if (image_comp->data) { |
102 | opj_image_data_free(image_comp->data); |
103 | } |
104 | } |
105 | opj_free(image->comps); |
106 | } |
107 | |
108 | if (image->icc_profile_buf) { |
109 | opj_free(image->icc_profile_buf); |
110 | } |
111 | |
112 | opj_free(image); |
113 | } |
114 | } |
115 | |
116 | /** |
117 | * Updates the components characteristics of the image from the coding parameters. |
118 | * |
119 | * @param p_image_header the image header to update. |
120 | * @param p_cp the coding parameters from which to update the image. |
121 | */ |
122 | void (opj_image_t * , |
123 | const struct opj_cp * p_cp) |
124 | { |
125 | OPJ_UINT32 i, l_width, l_height; |
126 | OPJ_UINT32 l_x0, l_y0, l_x1, l_y1; |
127 | OPJ_UINT32 l_comp_x0, l_comp_y0, l_comp_x1, l_comp_y1; |
128 | opj_image_comp_t* l_img_comp = NULL; |
129 | |
130 | l_x0 = opj_uint_max(p_cp->tx0, p_image_header->x0); |
131 | l_y0 = opj_uint_max(p_cp->ty0, p_image_header->y0); |
132 | l_x1 = p_cp->tx0 + (p_cp->tw - 1U) * |
133 | p_cp->tdx; /* validity of p_cp members used here checked in opj_j2k_read_siz. Can't overflow. */ |
134 | l_y1 = p_cp->ty0 + (p_cp->th - 1U) * p_cp->tdy; /* can't overflow */ |
135 | l_x1 = opj_uint_min(opj_uint_adds(l_x1, p_cp->tdx), |
136 | p_image_header->x1); /* use add saturated to prevent overflow */ |
137 | l_y1 = opj_uint_min(opj_uint_adds(l_y1, p_cp->tdy), |
138 | p_image_header->y1); /* use add saturated to prevent overflow */ |
139 | |
140 | l_img_comp = p_image_header->comps; |
141 | for (i = 0; i < p_image_header->numcomps; ++i) { |
142 | l_comp_x0 = opj_uint_ceildiv(l_x0, l_img_comp->dx); |
143 | l_comp_y0 = opj_uint_ceildiv(l_y0, l_img_comp->dy); |
144 | l_comp_x1 = opj_uint_ceildiv(l_x1, l_img_comp->dx); |
145 | l_comp_y1 = opj_uint_ceildiv(l_y1, l_img_comp->dy); |
146 | l_width = opj_uint_ceildivpow2(l_comp_x1 - l_comp_x0, l_img_comp->factor); |
147 | l_height = opj_uint_ceildivpow2(l_comp_y1 - l_comp_y0, l_img_comp->factor); |
148 | l_img_comp->w = l_width; |
149 | l_img_comp->h = l_height; |
150 | l_img_comp->x0 = l_comp_x0; |
151 | l_img_comp->y0 = l_comp_y0; |
152 | ++l_img_comp; |
153 | } |
154 | } |
155 | |
156 | |
157 | /** |
158 | * Copy only header of image and its component header (no data are copied) |
159 | * if dest image have data, they will be freed |
160 | * |
161 | * @param p_image_src the src image |
162 | * @param p_image_dest the dest image |
163 | * |
164 | */ |
165 | void (const opj_image_t* p_image_src, |
166 | opj_image_t* p_image_dest) |
167 | { |
168 | OPJ_UINT32 compno; |
169 | |
170 | /* preconditions */ |
171 | assert(p_image_src != 00); |
172 | assert(p_image_dest != 00); |
173 | |
174 | p_image_dest->x0 = p_image_src->x0; |
175 | p_image_dest->y0 = p_image_src->y0; |
176 | p_image_dest->x1 = p_image_src->x1; |
177 | p_image_dest->y1 = p_image_src->y1; |
178 | |
179 | if (p_image_dest->comps) { |
180 | for (compno = 0; compno < p_image_dest->numcomps; compno++) { |
181 | opj_image_comp_t *image_comp = &(p_image_dest->comps[compno]); |
182 | if (image_comp->data) { |
183 | opj_image_data_free(image_comp->data); |
184 | } |
185 | } |
186 | opj_free(p_image_dest->comps); |
187 | p_image_dest->comps = NULL; |
188 | } |
189 | |
190 | p_image_dest->numcomps = p_image_src->numcomps; |
191 | |
192 | p_image_dest->comps = (opj_image_comp_t*) opj_malloc(p_image_dest->numcomps * |
193 | sizeof(opj_image_comp_t)); |
194 | if (!p_image_dest->comps) { |
195 | p_image_dest->comps = NULL; |
196 | p_image_dest->numcomps = 0; |
197 | return; |
198 | } |
199 | |
200 | for (compno = 0; compno < p_image_dest->numcomps; compno++) { |
201 | memcpy(&(p_image_dest->comps[compno]), |
202 | &(p_image_src->comps[compno]), |
203 | sizeof(opj_image_comp_t)); |
204 | p_image_dest->comps[compno].data = NULL; |
205 | } |
206 | |
207 | p_image_dest->color_space = p_image_src->color_space; |
208 | p_image_dest->icc_profile_len = p_image_src->icc_profile_len; |
209 | |
210 | if (p_image_dest->icc_profile_len) { |
211 | p_image_dest->icc_profile_buf = (OPJ_BYTE*)opj_malloc( |
212 | p_image_dest->icc_profile_len); |
213 | if (!p_image_dest->icc_profile_buf) { |
214 | p_image_dest->icc_profile_buf = NULL; |
215 | p_image_dest->icc_profile_len = 0; |
216 | return; |
217 | } |
218 | memcpy(p_image_dest->icc_profile_buf, |
219 | p_image_src->icc_profile_buf, |
220 | p_image_src->icc_profile_len); |
221 | } else { |
222 | p_image_dest->icc_profile_buf = NULL; |
223 | } |
224 | |
225 | return; |
226 | } |
227 | |
228 | opj_image_t* OPJ_CALLCONV opj_image_tile_create(OPJ_UINT32 numcmpts, |
229 | opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) |
230 | { |
231 | OPJ_UINT32 compno; |
232 | opj_image_t *image = 00; |
233 | |
234 | image = (opj_image_t*) opj_calloc(1, sizeof(opj_image_t)); |
235 | if (image) { |
236 | |
237 | image->color_space = clrspc; |
238 | image->numcomps = numcmpts; |
239 | |
240 | /* allocate memory for the per-component information */ |
241 | image->comps = (opj_image_comp_t*)opj_calloc(image->numcomps, |
242 | sizeof(opj_image_comp_t)); |
243 | if (!image->comps) { |
244 | opj_image_destroy(image); |
245 | return 00; |
246 | } |
247 | |
248 | /* create the individual image components */ |
249 | for (compno = 0; compno < numcmpts; compno++) { |
250 | opj_image_comp_t *comp = &image->comps[compno]; |
251 | comp->dx = cmptparms[compno].dx; |
252 | comp->dy = cmptparms[compno].dy; |
253 | comp->w = cmptparms[compno].w; |
254 | comp->h = cmptparms[compno].h; |
255 | comp->x0 = cmptparms[compno].x0; |
256 | comp->y0 = cmptparms[compno].y0; |
257 | comp->prec = cmptparms[compno].prec; |
258 | comp->sgnd = cmptparms[compno].sgnd; |
259 | comp->data = 0; |
260 | } |
261 | } |
262 | |
263 | return image; |
264 | } |
265 | |