History

update to current

Sigrid Solveig Haflínudóttir committed 3 years agomaster

Commit f7e5af41 parent 7cdf83972 files · +16016 −1840Browse files

Unified · Split

72 files
  1. .gitignore +3 −0
  2. jas_cm.c +307 −142
  3. jas_debug.c +183 −22
  4. jas_icc.c +435 −239
  5. jas_iccdata.c +10 −0
  6. jas_image.c +404 −203
  7. jas_init.c +949 −23
  8. jas_malloc.c +651 −0
  9. jas_seq.c +9 −7
  10. jas_stream.c +413 −157
  11. jas_string.c +216 −0
  12. jas_tvp.c +234 −0
  13. jas_version.c +69 −0
  14. jasper/jas_cm.h +249 −21
  15. jasper/jas_compiler.h +69 −25
  16. jasper/jas_config.h +73 −3
  17. jasper/jas_debug.h +100 −10
  18. jasper/jas_dll.h +4 −24
  19. jasper/jas_fix.h +97 −44
  20. jasper/jas_icc.h +142 −20
  21. jasper/jas_image.h +222 −100
  22. jasper/jas_init.h +391 −10
  23. jasper/jas_log.h +168 −0
  24. jasper/jas_malloc.h +272 −7
  25. jasper/jas_math.h +401 −32
  26. jasper/jas_seq.h +271 −56
  27. jasper/jas_stream.h +201 −77
  28. jasper/jas_string.h +150 −0
  29. jasper/jas_thread.h +795 −0
  30. jasper/jas_tvp.h +200 −0
  31. jasper/jas_types.h +109 −35
  32. jasper/jas_version.h +113 −0
  33. jasper/jasper.h +6 −0
  34. jp2.c +4 −1
  35. jp2_cod.c +160 −50
  36. jp2_cod.h +2 −2
  37. jp2_dec.c +113 −59
  38. jp2_enc.c +494 −0
  39. jpc_bs.c +7 −4
  40. jpc_bs.h +2 −2
  41. jpc_cod.c +109 −0
  42. jpc_cod.h +4 −0
  43. jpc_cs.c +312 −77
  44. jpc_cs.h +6 −0
  45. jpc_dec.c +415 −112
  46. jpc_dec.h +1 −0
  47. jpc_enc.c +2665 −0
  48. jpc_enc.h +650 −0
  49. jpc_fix.h +28 −15
  50. jpc_math.c +34 −0
  51. jpc_math.h +8 −0
  52. jpc_mqdec.c +22 −4
  53. jpc_mqdec.h +7 −0
  54. jpc_mqenc.c +386 −0
  55. jpc_mqenc.h +217 −0
  56. jpc_qmfb.c +131 −141
  57. jpc_t1cod.c +18 −15
  58. jpc_t1cod.h +2 −0
  59. jpc_t1dec.c +19 −17
  60. jpc_t1enc.c +895 −0
  61. jpc_t1enc.h +86 −0
  62. jpc_t2cod.c +153 −53
  63. jpc_t2cod.h +6 −0
  64. jpc_t2dec.c +47 −21
  65. jpc_t2enc.c +656 −0
  66. jpc_t2enc.h +105 −0
  67. jpc_tagtree.c +21 −6
  68. jpc_tagtree.h +3 −0
  69. jpc_tsfb.c +9 −4
  70. jpc_util.c +186 −0
  71. jpc_util.h +82 −0
  72. mklib +35 −0
.gitignore+3−0
@@ -0,0 +1,3 @@
1*.out
2*.[o0125678vqki]
3libjp2.a
jas_cm.c+307−142
@@ -65,10 +65,21 @@ · 64 unmodified lines
65 * $Id$65 * $Id$
66 */66 */
67 67
68/******************************************************************************\
69* Includes.
70\******************************************************************************/
71
72#define JAS_FOR_INTERNAL_USE_ONLY
73
68#include "jasper/jas_cm.h"74#include "jasper/jas_cm.h"
69#include "jasper/jas_icc.h"75#include "jasper/jas_icc.h"
70#include "jasper/jas_malloc.h"76#include "jasper/jas_malloc.h"
71#include "jasper/jas_math.h"77#include "jasper/jas_math.h"
78#include "jasper/jas_debug.h"
79
80/******************************************************************************\
81* Function prototypes.
82\******************************************************************************/
72 83
73static jas_cmprof_t *jas_cmprof_create(void);84static jas_cmprof_t *jas_cmprof_create(void);
74static void jas_cmshapmatlut_cleanup(jas_cmshapmatlut_t *);85static void jas_cmshapmatlut_cleanup(jas_cmshapmatlut_t *);
@@ -89,8 +100,10 @@ static int jas_cmpxformseq_appendcnvt(jas_cmpxformseq_t *pxformseq, · 14 unmodified lines
89 unsigned, unsigned);100 unsigned, unsigned);
90static int jas_cmpxformseq_resize(jas_cmpxformseq_t *pxformseq, unsigned n);101static int jas_cmpxformseq_resize(jas_cmpxformseq_t *pxformseq, unsigned n);
91 102
92static int mono(const jas_iccprof_t *prof, int op, jas_cmpxformseq_t **pxformseq);103static int mono(const jas_iccprof_t *prof, int op,
93static int triclr(const jas_iccprof_t *prof, int op, jas_cmpxformseq_t **retpxformseq);104 jas_cmpxformseq_t **pxformseq);
105static int triclr(const jas_iccprof_t *prof, int op,
106 jas_cmpxformseq_t **retpxformseq);
94 107
95static void jas_cmpxformseq_destroy(jas_cmpxformseq_t *pxformseq);108static void jas_cmpxformseq_destroy(jas_cmpxformseq_t *pxformseq);
96static int jas_cmpxformseq_delete(jas_cmpxformseq_t *pxformseq, unsigned i);109static int jas_cmpxformseq_delete(jas_cmpxformseq_t *pxformseq, unsigned i);
@@ -100,6 +113,10 @@ static int jas_cmshapmat_invmat(jas_cmreal_t out[3][4], jas_cmreal_t in[3][4]); · 3 unmodified lines
100static int jas_cmpxformseq_insertpxform(jas_cmpxformseq_t *pxformseq,113static int jas_cmpxformseq_insertpxform(jas_cmpxformseq_t *pxformseq,
101 int i, jas_cmpxform_t *pxform);114 int i, jas_cmpxform_t *pxform);
102 115
116/******************************************************************************\
117* Function prototypes.
118\******************************************************************************/
119
103#define SEQFWD(intent) (intent)120#define SEQFWD(intent) (intent)
104#define SEQREV(intent) (4 + (intent))121#define SEQREV(intent) (4 + (intent))
105#define SEQSIM(intent) (8 + (intent))122#define SEQSIM(intent) (8 + (intent))
@@ -122,62 +139,81 @@ static int jas_cmpxformseq_insertpxform(jas_cmpxformseq_t *pxformseq, · 16 unmodified lines
122 139
123#define gampxformseq(prof) ((prof)->pxformseqs[SEQGAM])140#define gampxformseq(prof) ((prof)->pxformseqs[SEQGAM])
124 141
125static jas_clrspc_t icctoclrspc(jas_iccsig_t iccclrspc, int refflag);142static int icctoclrspc(jas_iccsig_t iccclrspc, jas_clrspc_t* clrspc, int refflag);
126static jas_cmpxform_t *jas_cmpxform_create0(void);143static jas_cmpxform_t *jas_cmpxform_create0(void);
127static jas_cmpxform_t *jas_cmpxform_createshapmat(void);144static jas_cmpxform_t *jas_cmpxform_createshapmat(void);
128static void jas_cmshapmatlut_init(jas_cmshapmatlut_t *lut);145static void jas_cmshapmatlut_init(jas_cmshapmatlut_t *lut);
129static int jas_cmshapmatlut_set(jas_cmshapmatlut_t *lut, const jas_icccurv_t *curv);146static int jas_cmshapmatlut_set(jas_cmshapmatlut_t *lut, const jas_icccurv_t *curv);
130
131static const jas_cmpxformops_t shapmat_ops = {jas_cmshapmat_destroy, jas_cmshapmat_apply};
132static jas_cmprof_t *jas_cmprof_createsycc(void);147static jas_cmprof_t *jas_cmprof_createsycc(void);
133 148
149/******************************************************************************\
150*
151\******************************************************************************/
152
153static const jas_cmpxformops_t shapmat_ops = {
154 jas_cmshapmat_destroy,
155 jas_cmshapmat_apply,
156 0
157};
158
134/******************************************************************************\159/******************************************************************************\
135* Color profile class.160* Color profile class.
136\******************************************************************************/161\******************************************************************************/
137 162
138jas_cmprof_t *jas_cmprof_createfromclrspc(jas_clrspc_t clrspc)163jas_cmprof_t *jas_cmprof_createfromclrspc(jas_clrspc_t clrspc)
139{164{
165 JAS_LOGDEBUGF(1, "jas_cmprof_createfromclrspc(%d)\n", clrspc);
166
140 jas_iccprof_t *iccprof;167 jas_iccprof_t *iccprof;
141 jas_cmprof_t *prof;168 jas_cmprof_t *prof;
142 169
143 iccprof = 0;170 iccprof = 0;
144 switch (clrspc) {171 switch (clrspc) {
145 case JAS_CLRSPC_SYCBCR:172 case JAS_CLRSPC_SYCBCR:
146 if (!(prof = jas_cmprof_createsycc()))173 if (!(prof = jas_cmprof_createsycc())) {
147 goto error;174 goto error;
175 }
148 break;176 break;
149 default:177 default:
150 if (!(iccprof = jas_iccprof_createfromclrspc(clrspc)))178 if (!(iccprof = jas_iccprof_createfromclrspc(clrspc))) {
151 goto error;179 goto error;
152 if (!(prof = jas_cmprof_createfromiccprof(iccprof)))180 }
181 if (!(prof = jas_cmprof_createfromiccprof(iccprof))) {
153 goto error;182 goto error;
183 }
154 jas_iccprof_destroy(iccprof);184 jas_iccprof_destroy(iccprof);
155 if (!jas_clrspc_isgeneric(clrspc))185 if (!jas_clrspc_isgeneric(clrspc)) {
156 prof->clrspc = clrspc;186 prof->clrspc = clrspc;
187 }
157 break;188 break;
158 }189 }
159 return prof;190 return prof;
160error:191error:
161 if (iccprof)192 if (iccprof) {
162 jas_iccprof_destroy(iccprof);193 jas_iccprof_destroy(iccprof);
194 }
163 return 0;195 return 0;
164}196}
165 197
166static jas_cmprof_t *jas_cmprof_createsycc()198static jas_cmprof_t *jas_cmprof_createsycc()
167{199{
200 JAS_LOGDEBUGF(1, "jas_cmprof_createsycc()\n");
201
168 jas_cmprof_t *prof;202 jas_cmprof_t *prof;
169 jas_cmpxform_t *fwdpxform = NULL;203 jas_cmpxform_t *fwdpxform = 0;
170 jas_cmpxform_t *revpxform = NULL;204 jas_cmpxform_t *revpxform = 0;
171 jas_cmshapmat_t *fwdshapmat;205 jas_cmshapmat_t *fwdshapmat;
172 jas_cmshapmat_t *revshapmat;206 jas_cmshapmat_t *revshapmat;
173 207
174 if (!(prof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB)))208 if (!(prof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) {
175 goto error;209 goto error;
210 }
176 prof->clrspc = JAS_CLRSPC_SYCBCR;211 prof->clrspc = JAS_CLRSPC_SYCBCR;
177 assert(prof->numchans == 3 && prof->numrefchans == 3);212 assert(prof->numchans == 3 && prof->numrefchans == 3);
178 assert(prof->refclrspc == JAS_CLRSPC_CIEXYZ);213 assert(prof->refclrspc == JAS_CLRSPC_CIEXYZ);
179 if (!(fwdpxform = jas_cmpxform_createshapmat()))214 if (!(fwdpxform = jas_cmpxform_createshapmat())) {
180 goto error;215 goto error;
216 }
181 fwdpxform->numinchans = 3;217 fwdpxform->numinchans = 3;
182 fwdpxform->numoutchans = 3;218 fwdpxform->numoutchans = 3;
183 fwdshapmat = &fwdpxform->data.shapmat;219 fwdshapmat = &fwdpxform->data.shapmat;
@@ -197,8 +233,9 @@ static jas_cmprof_t *jas_cmprof_createsycc() · 13 unmodified lines
197 fwdshapmat->mat[0][3] = -0.5 * (1.402);233 fwdshapmat->mat[0][3] = -0.5 * (1.402);
198 fwdshapmat->mat[1][3] = -0.5 * (-0.34413 - 0.71414);234 fwdshapmat->mat[1][3] = -0.5 * (-0.34413 - 0.71414);
199 fwdshapmat->mat[2][3] = -0.5 * (1.772);235 fwdshapmat->mat[2][3] = -0.5 * (1.772);
200 if (!(revpxform = jas_cmpxform_createshapmat()))236 if (!(revpxform = jas_cmpxform_createshapmat())) {
201 goto error;237 goto error;
238 }
202 revpxform->numinchans = 3;239 revpxform->numinchans = 3;
203 revpxform->numoutchans = 3;240 revpxform->numoutchans = 3;
204 revshapmat = &revpxform->data.shapmat;241 revshapmat = &revpxform->data.shapmat;
@@ -206,20 +243,24 @@ static jas_cmprof_t *jas_cmprof_createsycc() · 1 unmodified line
206 revshapmat->order = 1;243 revshapmat->order = 1;
207 revshapmat->useluts = 0;244 revshapmat->useluts = 0;
208 revshapmat->usemat = 1;245 revshapmat->usemat = 1;
209 jas_cmshapmat_invmat(revshapmat->mat, fwdshapmat->mat);246 if (jas_cmshapmat_invmat(revshapmat->mat, fwdshapmat->mat)) {
247 goto error;
248 }
210 249
211 for (unsigned i = 0; i < JAS_CMXFORM_NUMINTENTS; ++i) {250 for (unsigned i = 0; i < JAS_CMXFORM_NUMINTENTS; ++i) {
212 unsigned j = SEQFWD(i);251 unsigned j = SEQFWD(i);
213 if (prof->pxformseqs[j]) {252 if (prof->pxformseqs[j]) {
214 if (jas_cmpxformseq_insertpxform(prof->pxformseqs[j], 0,253 if (jas_cmpxformseq_insertpxform(prof->pxformseqs[j], 0,
215 fwdpxform))254 fwdpxform)) {
216 goto error;255 goto error;
256 }
217 }257 }
218 j = SEQREV(i);258 j = SEQREV(i);
219 if (prof->pxformseqs[j]) {259 if (prof->pxformseqs[j]) {
220 if (jas_cmpxformseq_insertpxform(prof->pxformseqs[j],260 if (jas_cmpxformseq_insertpxform(prof->pxformseqs[j],
221 -1, revpxform))261 -1, revpxform)) {
222 goto error;262 goto error;
263 }
223 }264 }
224 }265 }
225 266
@@ -227,15 +268,22 @@ static jas_cmprof_t *jas_cmprof_createsycc() · 1 unmodified line
227 jas_cmpxform_destroy(revpxform);268 jas_cmpxform_destroy(revpxform);
228 return prof;269 return prof;
229error:270error:
230 if (fwdpxform)271 if (fwdpxform) {
231 jas_cmpxform_destroy(fwdpxform);272 jas_cmpxform_destroy(fwdpxform);
232 if (revpxform)273 }
274 if (revpxform) {
233 jas_cmpxform_destroy(revpxform);275 jas_cmpxform_destroy(revpxform);
276 }
277 if (prof) {
278 jas_cmprof_destroy(prof);
279 }
234 return 0;280 return 0;
235}281}
236 282
237jas_cmprof_t *jas_cmprof_createfromiccprof(const jas_iccprof_t *iccprof)283jas_cmprof_t *jas_cmprof_createfromiccprof(const jas_iccprof_t *iccprof)
238{284{
285 JAS_LOGDEBUGF(1, "jas_cmprof_createfromiccprof(%p)\n", iccprof);
286
239 jas_cmprof_t *prof;287 jas_cmprof_t *prof;
240 jas_icchdr_t icchdr;288 jas_icchdr_t icchdr;
241 jas_cmpxformseq_t *fwdpxformseq;289 jas_cmpxformseq_t *fwdpxformseq;
@@ -244,26 +292,44 @@ jas_cmprof_t *jas_cmprof_createfromiccprof(const jas_iccprof_t *iccprof) · 2 unmodified lines
244 fwdpxformseq = 0;292 fwdpxformseq = 0;
245 revpxformseq = 0;293 revpxformseq = 0;
246 294
247 if (!(prof = jas_cmprof_create()))295 if (!(prof = jas_cmprof_create())) {
296 jas_logerrorf("error: cannot create CM profile\n");
248 goto error;297 goto error;
298 }
249 jas_iccprof_gethdr(iccprof, &icchdr);299 jas_iccprof_gethdr(iccprof, &icchdr);
250 if (!(prof->iccprof = jas_iccprof_copy(iccprof)))300 if (!(prof->iccprof = jas_iccprof_copy(iccprof))) {
301 jas_logerrorf("error: cannot copy ICC profile\n");
251 goto error;302 goto error;
252 prof->clrspc = icctoclrspc(icchdr.colorspc, 0);303 }
253 prof->refclrspc = icctoclrspc(icchdr.refcolorspc, 1);304 if (icctoclrspc(icchdr.colorspc, &prof->clrspc, 0)) {
305 jas_logerrorf("error: unknown color profile\n");
306 goto error;
307 }
308 if (icctoclrspc(icchdr.refcolorspc, &prof->refclrspc, 1)) {
309 jas_logerrorf("error: unknown reference color profile\n");
310 goto error;
311 }
254 prof->numchans = jas_clrspc_numchans(prof->clrspc);312 prof->numchans = jas_clrspc_numchans(prof->clrspc);
255 prof->numrefchans = jas_clrspc_numchans(prof->refclrspc);313 prof->numrefchans = jas_clrspc_numchans(prof->refclrspc);
256 314
257 if (prof->numchans == 1) {315 if (prof->numchans == 1) {
258 if (mono(prof->iccprof, 0, &fwdpxformseq))316 if (mono(prof->iccprof, 0, &fwdpxformseq)) {
317 jas_logerrorf("error: mono failed 1\n");
259 goto error;318 goto error;
260 if (mono(prof->iccprof, 1, &revpxformseq))319 }
320 if (mono(prof->iccprof, 1, &revpxformseq)) {
321 jas_logerrorf("error: mono failed 2\n");
261 goto error;322 goto error;
323 }
262 } else if (prof->numchans == 3) {324 } else if (prof->numchans == 3) {
263 if (triclr(prof->iccprof, 0, &fwdpxformseq))325 if (triclr(prof->iccprof, 0, &fwdpxformseq)) {
326 jas_logerrorf("error: triclr failed 1\n");
264 goto error;327 goto error;
265 if (triclr(prof->iccprof, 1, &revpxformseq))328 }
329 if (triclr(prof->iccprof, 1, &revpxformseq)) {
330 jas_logerrorf("error: triclr failed 2\n");
266 goto error;331 goto error;
332 }
267 }333 }
268 prof->pxformseqs[SEQFWD(0)] = fwdpxformseq;334 prof->pxformseqs[SEQFWD(0)] = fwdpxformseq;
269 prof->pxformseqs[SEQREV(0)] = revpxformseq;335 prof->pxformseqs[SEQREV(0)] = revpxformseq;
@@ -304,12 +370,14 @@ error: · 34 unmodified lines
304static jas_cmprof_t *jas_cmprof_create()370static jas_cmprof_t *jas_cmprof_create()
305{371{
306 jas_cmprof_t *prof;372 jas_cmprof_t *prof;
307 if (!(prof = jas_malloc(sizeof(jas_cmprof_t))))373 if (!(prof = jas_malloc(sizeof(jas_cmprof_t)))) {
308 return 0;374 return 0;
375 }
309 memset(prof, 0, sizeof(jas_cmprof_t));376 memset(prof, 0, sizeof(jas_cmprof_t));
310 prof->iccprof = 0;377 prof->iccprof = 0;
311 for (unsigned i = 0; i < JAS_CMPROF_NUMPXFORMSEQS; ++i)378 for (unsigned i = 0; i < JAS_CMPROF_NUMPXFORMSEQS; ++i) {
312 prof->pxformseqs[i] = 0;379 prof->pxformseqs[i] = 0;
380 }
313 return prof;381 return prof;
314}382}
315 383
@@ -321,8 +389,9 @@ void jas_cmprof_destroy(jas_cmprof_t *prof) · 5 unmodified lines
321 prof->pxformseqs[i] = 0;389 prof->pxformseqs[i] = 0;
322 }390 }
323 }391 }
324 if (prof->iccprof)392 if (prof->iccprof) {
325 jas_iccprof_destroy(prof->iccprof);393 jas_iccprof_destroy(prof->iccprof);
394 }
326 jas_free(prof);395 jas_free(prof);
327}396}
328 397
@@ -330,8 +399,9 @@ jas_cmprof_t *jas_cmprof_copy(const jas_cmprof_t *prof) · 1 unmodified line
330{399{
331 jas_cmprof_t *newprof;400 jas_cmprof_t *newprof;
332 401
333 if (!(newprof = jas_cmprof_create()))402 if (!(newprof = jas_cmprof_create())) {
334 goto error;403 goto error;
404 }
335 newprof->clrspc = prof->clrspc;405 newprof->clrspc = prof->clrspc;
336 newprof->numchans = prof->numchans;406 newprof->numchans = prof->numchans;
337 newprof->refclrspc = prof->refclrspc;407 newprof->refclrspc = prof->refclrspc;
@@ -345,8 +415,9 @@ jas_cmprof_t *jas_cmprof_copy(const jas_cmprof_t *prof) · 7 unmodified lines
345 }415 }
346 return newprof;416 return newprof;
347error:417error:
348 if (newprof)418 if (newprof) {
349 jas_cmprof_destroy(newprof);419 jas_cmprof_destroy(newprof);
420 }
350 return 0;421 return 0;
351}422}
352 423
@@ -363,40 +434,45 @@ jas_cmxform_t *jas_cmxform_create(const jas_cmprof_t *inprof, const jas_cmprof_t · 10 unmodified lines
363 jas_cmpxformseq_t *altoutpxformseq;434 jas_cmpxformseq_t *altoutpxformseq;
364 jas_cmpxformseq_t *prfpxformseq;435 jas_cmpxformseq_t *prfpxformseq;
365 436
366 /* Avoid compiler warnings about unused parameters. */437 JAS_UNUSED(optimize);
367 (void)optimize;
368 438
369 const jas_cmxform_intent_t prfintent = intent;439 const jas_cmxform_intent_t prfintent = intent;
370 440
371 if (!(xform = jas_malloc(sizeof(jas_cmxform_t))))441 if (!(xform = jas_malloc(sizeof(jas_cmxform_t)))) {
372 goto error;442 goto error;
373 if (!(xform->pxformseq = jas_cmpxformseq_create()))443 }
444 if (!(xform->pxformseq = jas_cmpxformseq_create())) {
374 goto error;445 goto error;
446 }
375 447
376 switch (op) {448 switch (op) {
377 case JAS_CMXFORM_OP_FWD:449 case JAS_CMXFORM_OP_FWD:
378 inpxformseq = fwdpxformseq(inprof, intent);450 inpxformseq = fwdpxformseq(inprof, intent);
379 outpxformseq = revpxformseq(outprof, intent);451 outpxformseq = revpxformseq(outprof, intent);
380 if (!inpxformseq || !outpxformseq)452 if (!inpxformseq || !outpxformseq) {
381 goto error;453 goto error;
454 }
382 if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) ||455 if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) ||
383 jas_cmpxformseq_appendcnvt(xform->pxformseq,456 jas_cmpxformseq_appendcnvt(xform->pxformseq,
384 inprof->refclrspc, outprof->refclrspc) ||457 inprof->refclrspc, outprof->refclrspc) ||
385 jas_cmpxformseq_append(xform->pxformseq, outpxformseq))458 jas_cmpxformseq_append(xform->pxformseq, outpxformseq)) {
386 goto error;459 goto error;
460 }
387 xform->numinchans = jas_clrspc_numchans(inprof->clrspc);461 xform->numinchans = jas_clrspc_numchans(inprof->clrspc);
388 xform->numoutchans = jas_clrspc_numchans(outprof->clrspc);462 xform->numoutchans = jas_clrspc_numchans(outprof->clrspc);
389 break;463 break;
390 case JAS_CMXFORM_OP_REV:464 case JAS_CMXFORM_OP_REV:
391 outpxformseq = fwdpxformseq(outprof, intent);465 outpxformseq = fwdpxformseq(outprof, intent);
392 inpxformseq = revpxformseq(inprof, intent);466 inpxformseq = revpxformseq(inprof, intent);
393 if (!outpxformseq || !inpxformseq)467 if (!outpxformseq || !inpxformseq) {
394 goto error;468 goto error;
469 }
395 if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq) ||470 if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq) ||
396 jas_cmpxformseq_appendcnvt(xform->pxformseq,471 jas_cmpxformseq_appendcnvt(xform->pxformseq,
397 outprof->refclrspc, inprof->refclrspc) ||472 outprof->refclrspc, inprof->refclrspc) ||
398 jas_cmpxformseq_append(xform->pxformseq, inpxformseq))473 jas_cmpxformseq_append(xform->pxformseq, inpxformseq)) {
399 goto error;474 goto error;
475 }
400 xform->numinchans = jas_clrspc_numchans(outprof->clrspc);476 xform->numinchans = jas_clrspc_numchans(outprof->clrspc);
401 xform->numoutchans = jas_clrspc_numchans(inprof->clrspc);477 xform->numoutchans = jas_clrspc_numchans(inprof->clrspc);
402 break;478 break;
@@ -404,53 +480,62 @@ jas_cmxform_t *jas_cmxform_create(const jas_cmprof_t *inprof, const jas_cmprof_t · 1 unmodified line
404 assert(prfprof);480 assert(prfprof);
405 inpxformseq = fwdpxformseq(inprof, intent);481 inpxformseq = fwdpxformseq(inprof, intent);
406 prfpxformseq = fwdpxformseq(prfprof, prfintent);482 prfpxformseq = fwdpxformseq(prfprof, prfintent);
407 if (!inpxformseq || !prfpxformseq)483 if (!inpxformseq || !prfpxformseq) {
408 goto error;484 goto error;
485 }
409 outpxformseq = simpxformseq(outprof, intent);486 outpxformseq = simpxformseq(outprof, intent);
410 altoutpxformseq = 0;487 altoutpxformseq = 0;
411 if (!outpxformseq) {488 if (!outpxformseq) {
412 outpxformseq = revpxformseq(outprof, intent);489 outpxformseq = revpxformseq(outprof, intent);
413 altoutpxformseq = fwdpxformseq(outprof, intent);490 altoutpxformseq = fwdpxformseq(outprof, intent);
414 if (!outpxformseq || !altoutpxformseq)491 if (!outpxformseq || !altoutpxformseq) {
415 goto error;492 goto error;
493 }
416 }494 }
417 if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) ||495 if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) ||
418 jas_cmpxformseq_appendcnvt(xform->pxformseq,496 jas_cmpxformseq_appendcnvt(xform->pxformseq,
419 inprof->refclrspc, outprof->refclrspc))497 inprof->refclrspc, outprof->refclrspc)) {
420 goto error;498 goto error;
499 }
421 if (altoutpxformseq) {500 if (altoutpxformseq) {
422 if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq) ||501 if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq) ||
423 jas_cmpxformseq_append(xform->pxformseq, altoutpxformseq))502 jas_cmpxformseq_append(xform->pxformseq, altoutpxformseq)) {
424 goto error;503 goto error;
504 }
425 } else {505 } else {
426 if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq))506 if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq)) {
427 goto error;507 goto error;
508 }
428 }509 }
429 if (jas_cmpxformseq_appendcnvt(xform->pxformseq,510 if (jas_cmpxformseq_appendcnvt(xform->pxformseq,
430 outprof->refclrspc, inprof->refclrspc) ||511 outprof->refclrspc, inprof->refclrspc) ||
431 jas_cmpxformseq_append(xform->pxformseq, prfpxformseq))512 jas_cmpxformseq_append(xform->pxformseq, prfpxformseq)) {
432 goto error;513 goto error;
514 }
433 xform->numinchans = jas_clrspc_numchans(inprof->clrspc);515 xform->numinchans = jas_clrspc_numchans(inprof->clrspc);
434 xform->numoutchans = jas_clrspc_numchans(prfprof->clrspc);516 xform->numoutchans = jas_clrspc_numchans(prfprof->clrspc);
435 break;517 break;
436 case JAS_CMXFORM_OP_GAMUT:518 case JAS_CMXFORM_OP_GAMUT:
437 inpxformseq = fwdpxformseq(inprof, intent);519 inpxformseq = fwdpxformseq(inprof, intent);
438 outpxformseq = gampxformseq(outprof);520 outpxformseq = gampxformseq(outprof);
439 if (!inpxformseq || !outpxformseq)521 if (!inpxformseq || !outpxformseq) {
440 goto error;522 goto error;
523 }
441 if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) ||524 if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) ||
442 jas_cmpxformseq_appendcnvt(xform->pxformseq,525 jas_cmpxformseq_appendcnvt(xform->pxformseq,
443 inprof->refclrspc, outprof->refclrspc) ||526 inprof->refclrspc, outprof->refclrspc) ||
444 jas_cmpxformseq_append(xform->pxformseq, outpxformseq))527 jas_cmpxformseq_append(xform->pxformseq, outpxformseq)) {
445 goto error;528 goto error;
529 }
446 xform->numinchans = jas_clrspc_numchans(inprof->clrspc);530 xform->numinchans = jas_clrspc_numchans(inprof->clrspc);
447 xform->numoutchans = 1;531 xform->numoutchans = 1;
448 break;532 break;
449 }533 }
450 return xform;534 return xform;
451error:535error:
452 if (xform)536 if (xform) {
453 jas_cmxform_destroy(xform);537 jas_cmxform_destroy(xform);
538 }
454 return 0;539 return 0;
455}540}
456 541
@@ -463,8 +548,10 @@ int jas_cmxform_apply(const jas_cmxform_t *xform, const jas_cmpixmap_t *in, jas_ · 6 unmodified lines
463 jas_cmreal_t scale;548 jas_cmreal_t scale;
464 long v;549 long v;
465 550
466 if (xform->numinchans > in->numcmpts || xform->numoutchans > out->numcmpts)551 if (xform->numinchans > in->numcmpts ||
552 xform->numoutchans > out->numcmpts) {
467 goto error;553 goto error;
554 }
468 555
469 const jas_cmcmptfmt_t *fmt = &in->cmptfmts[0];556 const jas_cmcmptfmt_t *fmt = &in->cmptfmts[0];
470 const unsigned width = fmt->width;557 const unsigned width = fmt->width;
@@ -494,9 +581,10 @@ int jas_cmxform_apply(const jas_cmxform_t *xform, const jas_cmpixmap_t *in, jas_ · 23 unmodified lines
494 }581 }
495 }582 }
496 583
497 if (maxchans == 0)584 if (maxchans == 0) {
498 /* avoid division by zero */585 /* avoid division by zero */
499 goto error;586 goto error;
587 }
500 588
501 const unsigned bufmax = APPLYBUFSIZ / maxchans;589 const unsigned bufmax = APPLYBUFSIZ / maxchans;
502 assert(bufmax > 0);590 assert(bufmax > 0);
@@ -515,8 +603,9 @@ int jas_cmxform_apply(const jas_cmxform_t *xform, const jas_cmpixmap_t *in, jas_ · 12 unmodified lines
515 const long *dataptr = &fmt->buf[n];603 const long *dataptr = &fmt->buf[n];
516 jas_cmreal_t *bufptr = &inbuf[i];604 jas_cmreal_t *bufptr = &inbuf[i];
517 for (unsigned j = 0; j < m; ++j) {605 for (unsigned j = 0; j < m; ++j) {
518 if (jas_cmgetint(&dataptr, fmt->sgnd, fmt->prec, &v))606 if (jas_cmgetint(&dataptr, fmt->sgnd, fmt->prec, &v)) {
519 goto error;607 goto error;
608 }
520 *bufptr = (jas_cmreal_t)(v - bias) / scale;609 *bufptr = (jas_cmreal_t)(v - bias) / scale;
521 bufptr += xform->numinchans;610 bufptr += xform->numinchans;
522 }611 }
@@ -531,8 +620,9 @@ int jas_cmxform_apply(const jas_cmxform_t *xform, const jas_cmpixmap_t *in, jas_ · 8 unmodified lines
531 } else {620 } else {
532 outbuf = inbuf;621 outbuf = inbuf;
533 }622 }
534 if ((*pxform->ops->apply)(pxform, inbuf, outbuf, m))623 if ((*pxform->ops->apply)(pxform, inbuf, outbuf, m)) {
535 goto error;624 goto error;
625 }
536 inbuf = outbuf;626 inbuf = outbuf;
537 }627 }
538 628
@@ -545,8 +635,9 @@ int jas_cmxform_apply(const jas_cmxform_t *xform, const jas_cmpixmap_t *in, jas_ · 6 unmodified lines
545 for (unsigned j = 0; j < m; ++j) {635 for (unsigned j = 0; j < m; ++j) {
546 v = (long)((*bufptr) * scale + bias);636 v = (long)((*bufptr) * scale + bias);
547 bufptr += xform->numoutchans;637 bufptr += xform->numoutchans;
548 if (jas_cmputint(&dataptr, fmt->sgnd, fmt->prec, v))638 if (jas_cmputint(&dataptr, fmt->sgnd, fmt->prec, v)) {
549 goto error;639 goto error;
640 }
550 }641 }
551 }642 }
552 643
@@ -560,8 +651,9 @@ error: · 7 unmodified lines
560 651
561void jas_cmxform_destroy(jas_cmxform_t *xform)652void jas_cmxform_destroy(jas_cmxform_t *xform)
562{653{
563 if (xform->pxformseq)654 if (xform->pxformseq) {
564 jas_cmpxformseq_destroy(xform->pxformseq);655 jas_cmpxformseq_destroy(xform->pxformseq);
656 }
565 jas_free(xform);657 jas_free(xform);
566}658}
567 659
@@ -572,17 +664,20 @@ void jas_cmxform_destroy(jas_cmxform_t *xform) · 4 unmodified lines
572static jas_cmpxformseq_t *jas_cmpxformseq_create()664static jas_cmpxformseq_t *jas_cmpxformseq_create()
573{665{
574 jas_cmpxformseq_t *pxformseq;666 jas_cmpxformseq_t *pxformseq;
575 if (!(pxformseq = jas_malloc(sizeof(jas_cmpxformseq_t))))667 if (!(pxformseq = jas_malloc(sizeof(jas_cmpxformseq_t)))) {
576 goto error;668 goto error;
669 }
577 pxformseq->pxforms = 0;670 pxformseq->pxforms = 0;
578 pxformseq->numpxforms = 0;671 pxformseq->numpxforms = 0;
579 pxformseq->maxpxforms = 0;672 pxformseq->maxpxforms = 0;
580 if (jas_cmpxformseq_resize(pxformseq, 16))673 if (jas_cmpxformseq_resize(pxformseq, 16)) {
581 goto error;674 goto error;
675 }
582 return pxformseq;676 return pxformseq;
583error:677error:
584 if (pxformseq)678 if (pxformseq) {
585 jas_cmpxformseq_destroy(pxformseq);679 jas_cmpxformseq_destroy(pxformseq);
680 }
586 return 0;681 return 0;
587}682}
588 683
@@ -590,23 +685,28 @@ static jas_cmpxformseq_t *jas_cmpxformseq_copy(jas_cmpxformseq_t *pxformseq) · 1 unmodified line
590{685{
591 jas_cmpxformseq_t *newpxformseq;686 jas_cmpxformseq_t *newpxformseq;
592 687
593 if (!(newpxformseq = jas_cmpxformseq_create()))688 if (!(newpxformseq = jas_cmpxformseq_create())) {
594 goto error;689 goto error;
595 if (jas_cmpxformseq_append(newpxformseq, pxformseq))690 }
691 if (jas_cmpxformseq_append(newpxformseq, pxformseq)) {
596 goto error;692 goto error;
693 }
597 return newpxformseq;694 return newpxformseq;
598error:695error:
599 if (newpxformseq)696 if (newpxformseq) {
600 jas_cmpxformseq_destroy(newpxformseq);697 jas_cmpxformseq_destroy(newpxformseq);
698 }
601 return 0;699 return 0;
602}700}
603 701
604static void jas_cmpxformseq_destroy(jas_cmpxformseq_t *pxformseq)702static void jas_cmpxformseq_destroy(jas_cmpxformseq_t *pxformseq)
605{703{
606 while (pxformseq->numpxforms > 0)704 while (pxformseq->numpxforms > 0) {
607 jas_cmpxformseq_delete(pxformseq, pxformseq->numpxforms - 1);705 jas_cmpxformseq_delete(pxformseq, pxformseq->numpxforms - 1);
608 if (pxformseq->pxforms)706 }
707 if (pxformseq->pxforms) {
609 jas_free(pxformseq->pxforms);708 jas_free(pxformseq->pxforms);
709 }
610 jas_free(pxformseq);710 jas_free(pxformseq);
611}711}
612 712
@@ -623,11 +723,16 @@ static int jas_cmpxformseq_delete(jas_cmpxformseq_t *pxformseq, unsigned i) · 10 unmodified lines
623static int jas_cmpxformseq_appendcnvt(jas_cmpxformseq_t *pxformseq,723static int jas_cmpxformseq_appendcnvt(jas_cmpxformseq_t *pxformseq,
624 unsigned dstclrspc, unsigned srcclrspc)724 unsigned dstclrspc, unsigned srcclrspc)
625{725{
626 if (dstclrspc == srcclrspc)726 JAS_UNUSED(pxformseq);
727 if (dstclrspc == srcclrspc) {
627 return 0;728 return 0;
729 }
730 /*
731 I think that this function should not be called if the source and
732 destination color spaces are of different types.
733 That is, it is considered a programmer error, not a run-time error.
734 */
628 abort();735 abort();
629 /* Avoid compiler warnings about unused parameters. */
630 USED(pxformseq);
631 return -1;736 return -1;
632}737}
633 738
@@ -638,13 +743,14 @@ static int jas_cmpxformseq_insertpxform(jas_cmpxformseq_t *pxformseq, · 4 unmodified lines
638 const unsigned i = _i >= 0 ? (unsigned)_i : pxformseq->numpxforms;743 const unsigned i = _i >= 0 ? (unsigned)_i : pxformseq->numpxforms;
639 assert(i <= pxformseq->numpxforms);744 assert(i <= pxformseq->numpxforms);
640 if (pxformseq->numpxforms >= pxformseq->maxpxforms) {745 if (pxformseq->numpxforms >= pxformseq->maxpxforms) {
641 if (jas_cmpxformseq_resize(pxformseq, pxformseq->numpxforms +746 if (jas_cmpxformseq_resize(pxformseq, pxformseq->numpxforms + 16)) {
642 16))
643 goto error;747 goto error;
748 }
644 }749 }
645 assert(pxformseq->numpxforms < pxformseq->maxpxforms);750 assert(pxformseq->numpxforms < pxformseq->maxpxforms);
646 if (!(tmppxform = jas_cmpxform_copy(pxform)))751 if (!(tmppxform = jas_cmpxform_copy(pxform))) {
647 goto error;752 goto error;
753 }
648 const unsigned n = pxformseq->numpxforms - i;754 const unsigned n = pxformseq->numpxforms - i;
649 if (n > 0) {755 if (n > 0) {
650 memmove(&pxformseq->pxforms[i + 1], &pxformseq->pxforms[i],756 memmove(&pxformseq->pxforms[i + 1], &pxformseq->pxforms[i],
@@ -664,13 +770,15 @@ static int jas_cmpxformseq_append(jas_cmpxformseq_t *pxformseq, · 13 unmodified lines
664 jas_cmpxform_t *othpxform;770 jas_cmpxform_t *othpxform;
665 const unsigned n = pxformseq->numpxforms + othpxformseq->numpxforms;771 const unsigned n = pxformseq->numpxforms + othpxformseq->numpxforms;
666 if (n > pxformseq->maxpxforms) {772 if (n > pxformseq->maxpxforms) {
667 if (jas_cmpxformseq_resize(pxformseq, n))773 if (jas_cmpxformseq_resize(pxformseq, n)) {
668 goto error;774 goto error;
775 }
669 }776 }
670 for (unsigned i = 0; i < othpxformseq->numpxforms; ++i) {777 for (unsigned i = 0; i < othpxformseq->numpxforms; ++i) {
671 othpxform = othpxformseq->pxforms[i];778 othpxform = othpxformseq->pxforms[i];
672 if (!(pxform = jas_cmpxform_copy(othpxform)))779 if (!(pxform = jas_cmpxform_copy(othpxform))) {
673 goto error;780 goto error;
781 }
674 pxformseq->pxforms[pxformseq->numpxforms] = pxform;782 pxformseq->pxforms[pxformseq->numpxforms] = pxform;
675 ++pxformseq->numpxforms;783 ++pxformseq->numpxforms;
676 }784 }
@@ -700,8 +808,9 @@ static int jas_cmpxformseq_resize(jas_cmpxformseq_t *pxformseq, unsigned n) · 23 unmodified lines
700static jas_cmpxform_t *jas_cmpxform_create0()808static jas_cmpxform_t *jas_cmpxform_create0()
701{809{
702 jas_cmpxform_t *pxform;810 jas_cmpxform_t *pxform;
703 if (!(pxform = jas_malloc(sizeof(jas_cmpxform_t))))811 if (!(pxform = jas_malloc(sizeof(jas_cmpxform_t)))) {
704 return 0;812 return 0;
813 }
705 memset(pxform, 0, sizeof(jas_cmpxform_t));814 memset(pxform, 0, sizeof(jas_cmpxform_t));
706 pxform->refcnt = 0;815 pxform->refcnt = 0;
707 pxform->ops = 0;816 pxform->ops = 0;
@@ -730,19 +839,22 @@ static jas_cmpxform_t *jas_cmpxform_createshapmat() · 22 unmodified lines
730{839{
731 jas_cmpxform_t *pxform;840 jas_cmpxform_t *pxform;
732 jas_cmshapmat_t *shapmat;841 jas_cmshapmat_t *shapmat;
733 if (!(pxform = jas_cmpxform_create0()))842 if (!(pxform = jas_cmpxform_create0())) {
734 return 0;843 return 0;
844 }
735 pxform->ops = &shapmat_ops;845 pxform->ops = &shapmat_ops;
736 shapmat = &pxform->data.shapmat;846 shapmat = &pxform->data.shapmat;
737 shapmat->mono = 0;847 shapmat->mono = 0;
738 shapmat->order = 0;848 shapmat->order = 0;
739 shapmat->useluts = 0;849 shapmat->useluts = 0;
740 shapmat->usemat = 0;850 shapmat->usemat = 0;
741 for (unsigned i = 0; i < 3; ++i)851 for (unsigned i = 0; i < 3; ++i) {
742 jas_cmshapmatlut_init(&shapmat->luts[i]);852 jas_cmshapmatlut_init(&shapmat->luts[i]);
853 }
743 for (unsigned i = 0; i < 3; ++i) {854 for (unsigned i = 0; i < 3; ++i) {
744 for (unsigned j = 0; j < 4; ++j)855 for (unsigned j = 0; j < 4; ++j) {
745 shapmat->mat[i][j] = 0.0;856 shapmat->mat[i][j] = 0.0;
857 }
746 }858 }
747 ++pxform->refcnt;859 ++pxform->refcnt;
748 return pxform;860 return pxform;
@@ -751,8 +863,9 @@ static jas_cmpxform_t *jas_cmpxform_createshapmat() · 2 unmodified lines
751static void jas_cmshapmat_destroy(jas_cmpxform_t *pxform)863static void jas_cmshapmat_destroy(jas_cmpxform_t *pxform)
752{864{
753 jas_cmshapmat_t *shapmat = &pxform->data.shapmat;865 jas_cmshapmat_t *shapmat = &pxform->data.shapmat;
754 for (unsigned i = 0; i < 3; ++i)866 for (unsigned i = 0; i < 3; ++i) {
755 jas_cmshapmatlut_cleanup(&shapmat->luts[i]);867 jas_cmshapmatlut_cleanup(&shapmat->luts[i]);
868 }
756}869}
757 870
758static int jas_cmshapmat_apply(const jas_cmpxform_t *pxform, const jas_cmreal_t *in,871static int jas_cmshapmat_apply(const jas_cmpxform_t *pxform, const jas_cmreal_t *in,
@@ -808,8 +921,9 @@ static int jas_cmshapmat_apply(const jas_cmpxform_t *pxform, const jas_cmreal_t · 49 unmodified lines
808 if (!shapmat->order) {921 if (!shapmat->order) {
809 while (cnt-- > 0) {922 while (cnt-- > 0) {
810 a0 = *src++;923 a0 = *src++;
811 if (shapmat->useluts)924 if (shapmat->useluts) {
812 a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0);925 a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0);
926 }
813 a2 = a0 * shapmat->mat[2][0];927 a2 = a0 * shapmat->mat[2][0];
814 a1 = a0 * shapmat->mat[1][0];928 a1 = a0 * shapmat->mat[1][0];
815 a0 = a0 * shapmat->mat[0][0];929 a0 = a0 * shapmat->mat[0][0];
@@ -824,8 +938,9 @@ assert(0); · 8 unmodified lines
824 src++;938 src++;
825 src++;939 src++;
826 a0 = a0 * shapmat->mat[0][0];940 a0 = a0 * shapmat->mat[0][0];
827 if (shapmat->useluts)941 if (shapmat->useluts) {
828 a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0);942 a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0);
943 }
829 *dst++ = a0;944 *dst++ = a0;
830 }945 }
831 }946 }
@@ -851,8 +966,9 @@ static void jas_cmshapmatlut_cleanup(jas_cmshapmatlut_t *lut) · 19 unmodified lines
851 966
852static double gammafn(double x, double gamma)967static double gammafn(double x, double gamma)
853{968{
854 if (x == 0.0)969 if (x == 0.0) {
855 return 0.0;970 return 0.0;
971 }
856 return pow(x, gamma);972 return pow(x, gamma);
857}973}
858 974
@@ -862,28 +978,32 @@ static int jas_cmshapmatlut_set(jas_cmshapmatlut_t *lut, const jas_icccurv_t *cu · 3 unmodified lines
862 jas_cmshapmatlut_cleanup(lut);978 jas_cmshapmatlut_cleanup(lut);
863 if (curv->numents == 0) {979 if (curv->numents == 0) {
864 lut->size = 2;980 lut->size = 2;
865 if (!(lut->data = jas_alloc2(lut->size, sizeof(jas_cmreal_t))))981 if (!(lut->data = jas_alloc2(lut->size, sizeof(jas_cmreal_t)))) {
866 goto error;982 goto error;
983 }
867 lut->data[0] = 0.0;984 lut->data[0] = 0.0;
868 lut->data[1] = 1.0;985 lut->data[1] = 1.0;
869 } else if (curv->numents == 1) {986 } else if (curv->numents == 1) {
870 lut->size = 256;987 lut->size = 256;
871 if (!(lut->data = jas_alloc2(lut->size, sizeof(jas_cmreal_t))))988 if (!(lut->data = jas_alloc2(lut->size, sizeof(jas_cmreal_t)))) {
872 goto error;989 goto error;
990 }
873 gamma = (jas_cmreal_t)curv->ents[0] / 256.0;991 gamma = (jas_cmreal_t)curv->ents[0] / 256.0;
874 for (unsigned i = 0; i < lut->size; ++i) {992 for (unsigned i = 0; i < lut->size; ++i) {
875 lut->data[i] = gammafn(i / (double) (lut->size - 1), gamma);993 lut->data[i] = gammafn(i / (double) (lut->size - 1), gamma);
876 }994 }
877 } else {995 } else {
878 lut->size = curv->numents;996 lut->size = curv->numents;
879 if (!(lut->data = jas_alloc2(lut->size, sizeof(jas_cmreal_t))))997 if (!(lut->data = jas_alloc2(lut->size, sizeof(jas_cmreal_t)))) {
880 goto error;998 goto error;
999 }
881 for (unsigned i = 0; i < lut->size; ++i) {1000 for (unsigned i = 0; i < lut->size; ++i) {
882 lut->data[i] = (jas_cmreal_t)curv->ents[i] / 65535.0;1001 lut->data[i] = (jas_cmreal_t)curv->ents[i] / 65535.0;
883 }1002 }
884 }1003 }
885 return 0;1004 return 0;
886error:1005error:
1006 jas_cmshapmatlut_cleanup(lut);
887 return -1;1007 return -1;
888}1008}
889 1009
@@ -892,11 +1012,13 @@ static jas_cmreal_t jas_cmshapmatlut_lookup(const jas_cmshapmatlut_t *lut, jas_c · 2 unmodified lines
892 jas_cmreal_t t;1012 jas_cmreal_t t;
893 t = x * (lut->size - 1);1013 t = x * (lut->size - 1);
894 const int lo = (int)floor(t);1014 const int lo = (int)floor(t);
895 if (lo < 0)1015 if (lo < 0) {
896 return lut->data[0];1016 return lut->data[0];
1017 }
897 const unsigned hi = (unsigned)ceil(t);1018 const unsigned hi = (unsigned)ceil(t);
898 if (hi >= lut->size)1019 if (hi >= lut->size) {
899 return lut->data[lut->size - 1];1020 return lut->data[lut->size - 1];
1021 }
900 return lut->data[lo] + (t - lo) * (lut->data[hi] - lut->data[lo]);1022 return lut->data[lo] + (t - lo) * (lut->data[hi] - lut->data[lo]);
901}1023}
902 1024
@@ -921,8 +1043,9 @@ static int jas_cmshapmatlut_invert(jas_cmshapmatlut_t *invlut, · 18 unmodified lines
921 return -1;1043 return -1;
922 }1044 }
923 }1045 }
924 if (!(invlut->data = jas_alloc2(n, sizeof(jas_cmreal_t))))1046 if (!(invlut->data = jas_alloc2(n, sizeof(jas_cmreal_t)))) {
925 return -1;1047 return -1;
1048 }
926 invlut->size = n;1049 invlut->size = n;
927 for (unsigned i = 0; i < invlut->size; ++i) {1050 for (unsigned i = 0; i < invlut->size; ++i) {
928 sy = ((double) i) / (invlut->size - 1);1051 sy = ((double) i) / (invlut->size - 1);
@@ -933,11 +1056,9 @@ static int jas_cmshapmatlut_invert(jas_cmshapmatlut_t *invlut, · 4 unmodified lines
933 unsigned k;1056 unsigned k;
934 for (k = j + 1; k < lut->size; ++k) {1057 for (k = j + 1; k < lut->size; ++k) {
935 by = lut->data[k];1058 by = lut->data[k];
936 if (by != sy)1059 if (by != sy) {
937 break;1060 break;
938#if 01061 }
939assert(0);
940#endif
941 }1062 }
942 if (k < lut->size) {1063 if (k < lut->size) {
943 --k;1064 --k;
@@ -961,10 +1082,12 @@ assert(0); · 17 unmodified lines
961 invlut->data[i] = sx;1082 invlut->data[i] = sx;
962 }1083 }
963#if 01084#if 0
964for (i=0;i<lut->size;++i)1085 for (i=0;i<lut->size;++i) {
965 jas_eprintf("lut[%d]=%f ", i, lut->data[i]);1086 jas_eprintf("lut[%d]=%f ", i, lut->data[i]);
966for (i=0;i<invlut->size;++i)1087 }
967 jas_eprintf("invlut[%d]=%f ", i, invlut->data[i]);1088 for (i=0;i<invlut->size;++i) {
1089 jas_eprintf("invlut[%d]=%f ", i, invlut->data[i]);
1090 }
968#endif1091#endif
969 return 0;1092 return 0;
970}1093}
@@ -975,11 +1098,11 @@ static int jas_cmshapmat_invmat(jas_cmreal_t out[3][4], jas_cmreal_t in[3][4]) · 4 unmodified lines
975 d = in[0][0] * (in[1][1] * in[2][2] - in[1][2] * in[2][1])1098 d = in[0][0] * (in[1][1] * in[2][2] - in[1][2] * in[2][1])
976 - in[0][1] * (in[1][0] * in[2][2] - in[1][2] * in[2][0])1099 - in[0][1] * (in[1][0] * in[2][2] - in[1][2] * in[2][0])
977 + in[0][2] * (in[1][0] * in[2][1] - in[1][1] * in[2][0]);1100 + in[0][2] * (in[1][0] * in[2][1] - in[1][1] * in[2][0]);
978#if 01101 if (JAS_ABS(d) < 1e-6) {
979jas_eprintf("delta=%f\n", d);1102 jas_logerrorf("jas_cmshapmat_invmat: matrix is not invertible "
980#endif1103 "(determinant %a)\n", d);
981 if (JAS_ABS(d) < 1e-6)
982 return -1;1104 return -1;
1105 }
983 out[0][0] = (in[1][1] * in[2][2] - in[1][2] * in[2][1]) / d;1106 out[0][0] = (in[1][1] * in[2][2] - in[1][2] * in[2][1]) / d;
984 out[1][0] = -(in[1][0] * in[2][2] - in[1][2] * in[2][0]) / d;1107 out[1][0] = -(in[1][0] * in[2][2] - in[1][2] * in[2][0]) / d;
985 out[2][0] = (in[1][0] * in[2][1] - in[1][1] * in[2][0]) / d;1108 out[2][0] = (in[1][0] * in[2][1] - in[1][1] * in[2][0]) / d;
@@ -993,14 +1116,14 @@ jas_eprintf("delta=%f\n", d); · 7 unmodified lines
993 out[1][3] = -in[1][3];1116 out[1][3] = -in[1][3];
994 out[2][3] = -in[2][3];1117 out[2][3] = -in[2][3];
995#if 01118#if 0
996jas_eprintf("[ %f %f %f %f ]\n[ %f %f %f %f ]\n[ %f %f %f %f ]\n",1119 jas_eprintf("[ %f %f %f %f ]\n[ %f %f %f %f ]\n[ %f %f %f %f ]\n",
997in[0][0], in[0][1], in[0][2], in[0][3],1120 in[0][0], in[0][1], in[0][2], in[0][3],
998in[1][0], in[1][1], in[1][2], in[1][3],1121 in[1][0], in[1][1], in[1][2], in[1][3],
999in[2][0], in[2][1], in[2][2], in[2][3]);1122 in[2][0], in[2][1], in[2][2], in[2][3]);
1000jas_eprintf("[ %f %f %f %f ]\n[ %f %f %f %f ]\n[ %f %f %f %f ]\n",1123 jas_eprintf("[ %f %f %f %f ]\n[ %f %f %f %f ]\n[ %f %f %f %f ]\n",
1001out[0][0], out[0][1], out[0][2], out[0][3],1124 out[0][0], out[0][1], out[0][2], out[0][3],
1002out[1][0], out[1][1], out[1][2], out[1][3],1125 out[1][0], out[1][1], out[1][2], out[1][3],
1003out[2][0], out[2][1], out[2][2], out[2][3]);1126 out[2][0], out[2][1], out[2][2], out[2][3]);
1004#endif1127#endif
1005 return 0;1128 return 0;
1006}1129}
@@ -1009,30 +1132,34 @@ out[2][0], out[2][1], out[2][2], out[2][3]); · 2 unmodified lines
1009*1132*
1010\******************************************************************************/1133\******************************************************************************/
1011 1134
1012static jas_clrspc_t icctoclrspc(jas_iccsig_t iccclrspc, int refflag)1135static int icctoclrspc(jas_iccsig_t iccclrspc, jas_clrspc_t* clrspc, int refflag)
1013{1136{
1014 if (refflag) {1137 if (refflag) {
1015 switch (iccclrspc) {1138 switch (iccclrspc) {
1016 case JAS_ICC_COLORSPC_XYZ:1139 case JAS_ICC_COLORSPC_XYZ:
1017 return JAS_CLRSPC_CIEXYZ;1140 *clrspc = JAS_CLRSPC_CIEXYZ;
1141 return 0;
1018 case JAS_ICC_COLORSPC_LAB:1142 case JAS_ICC_COLORSPC_LAB:
1019 return JAS_CLRSPC_CIELAB;1143 *clrspc = JAS_CLRSPC_CIELAB;
1144 return 0;
1020 default:1145 default:
1021 abort();1146 return -1;
1022 }1147 }
1023 } else {1148 } else {
1024 switch (iccclrspc) {1149 switch (iccclrspc) {
1025 case JAS_ICC_COLORSPC_YCBCR:1150 case JAS_ICC_COLORSPC_YCBCR:
1026 return JAS_CLRSPC_GENYCBCR;1151 *clrspc = JAS_CLRSPC_GENYCBCR;
1152 return 0;
1027 case JAS_ICC_COLORSPC_RGB:1153 case JAS_ICC_COLORSPC_RGB:
1028 return JAS_CLRSPC_GENRGB;1154 *clrspc = JAS_CLRSPC_GENRGB;
1155 return 0;
1029 case JAS_ICC_COLORSPC_GRAY:1156 case JAS_ICC_COLORSPC_GRAY:
1030 return JAS_CLRSPC_GENGRAY;1157 *clrspc = JAS_CLRSPC_GENGRAY;
1158 return 0;
1031 default:1159 default:
1032 abort();1160 return -1;
1033 }1161 }
1034 }1162 }
1035 return -1;
1036}1163}
1037 1164
1038static int mono(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxformseq)1165static int mono(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxformseq)
@@ -1045,15 +1172,19 @@ static int mono(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxf · 6 unmodified lines
1045 1172
1046 jas_cmshapmatlut_init(&lut);1173 jas_cmshapmatlut_init(&lut);
1047 if (!(graytrc = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRYTRC)) ||1174 if (!(graytrc = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRYTRC)) ||
1048 graytrc->type != JAS_ICC_TYPE_CURV)1175 graytrc->type != JAS_ICC_TYPE_CURV) {
1049 goto error;1176 goto error;
1050 if (!(pxform = jas_cmpxform_createshapmat()))1177 }
1178 if (!(pxform = jas_cmpxform_createshapmat())) {
1051 goto error;1179 goto error;
1180 }
1052 shapmat = &pxform->data.shapmat;1181 shapmat = &pxform->data.shapmat;
1053 if (!(pxformseq = jas_cmpxformseq_create()))1182 if (!(pxformseq = jas_cmpxformseq_create())) {
1054 goto error;1183 goto error;
1055 if (jas_cmpxformseq_insertpxform(pxformseq, -1, pxform))1184 }
1185 if (jas_cmpxformseq_insertpxform(pxformseq, -1, pxform)) {
1056 goto error;1186 goto error;
1187 }
1057 1188
1058 pxform->numinchans = 1;1189 pxform->numinchans = 1;
1059 pxform->numoutchans = 3;1190 pxform->numoutchans = 3;
@@ -1066,18 +1197,21 @@ static int mono(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxf · 6 unmodified lines
1066 shapmat->mat[0][0] = 0.9642;1197 shapmat->mat[0][0] = 0.9642;
1067 shapmat->mat[1][0] = 1.0;1198 shapmat->mat[1][0] = 1.0;
1068 shapmat->mat[2][0] = 0.8249;1199 shapmat->mat[2][0] = 0.8249;
1069 if (jas_cmshapmatlut_set(&shapmat->luts[0], &graytrc->data.curv))1200 if (jas_cmshapmatlut_set(&shapmat->luts[0], &graytrc->data.curv)) {
1070 goto error;1201 goto error;
1202 }
1071 } else {1203 } else {
1072 shapmat->order = 1;1204 shapmat->order = 1;
1073 shapmat->mat[0][0] = 1.0 / 0.9642;1205 shapmat->mat[0][0] = 1.0 / 0.9642;
1074 shapmat->mat[1][0] = 1.0;1206 shapmat->mat[1][0] = 1.0;
1075 shapmat->mat[2][0] = 1.0 / 0.8249;1207 shapmat->mat[2][0] = 1.0 / 0.8249;
1076 jas_cmshapmatlut_init(&lut);1208 jas_cmshapmatlut_init(&lut);
1077 if (jas_cmshapmatlut_set(&lut, &graytrc->data.curv))1209 if (jas_cmshapmatlut_set(&lut, &graytrc->data.curv)) {
1078 goto error;1210 goto error;
1079 if (jas_cmshapmatlut_invert(&shapmat->luts[0], &lut, lut.size))1211 }
1212 if (jas_cmshapmatlut_invert(&shapmat->luts[0], &lut, lut.size)) {
1080 goto error;1213 goto error;
1214 }
1081 jas_cmshapmatlut_cleanup(&lut);1215 jas_cmshapmatlut_cleanup(&lut);
1082 }1216 }
1083 jas_iccattrval_destroy(graytrc);1217 jas_iccattrval_destroy(graytrc);
@@ -1085,16 +1219,21 @@ static int mono(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxf · 1 unmodified line
1085 *retpxformseq = pxformseq;1219 *retpxformseq = pxformseq;
1086 return 0;1220 return 0;
1087error:1221error:
1088 if (graytrc)1222 jas_cmshapmatlut_cleanup(&lut);
1223 if (graytrc) {
1089 jas_iccattrval_destroy(graytrc);1224 jas_iccattrval_destroy(graytrc);
1090 if (pxform)1225 }
1226 if (pxform) {
1091 jas_cmpxform_destroy(pxform);1227 jas_cmpxform_destroy(pxform);
1092 if (pxformseq)1228 }
1229 if (pxformseq) {
1093 jas_cmpxformseq_destroy(pxformseq);1230 jas_cmpxformseq_destroy(pxformseq);
1231 }
1094 return -1;1232 return -1;
1095}1233}
1096 1234
1097static int triclr(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxformseq)1235static int triclr(const jas_iccprof_t *iccprof, int op,
1236 jas_cmpxformseq_t **retpxformseq)
1098{1237{
1099 jas_iccattrval_t *trcs[3];1238 jas_iccattrval_t *trcs[3];
1100 jas_iccattrval_t *cols[3];1239 jas_iccattrval_t *cols[3];
@@ -1103,6 +1242,7 @@ static int triclr(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retp · 2 unmodified lines
1103 jas_cmpxformseq_t *pxformseq;1242 jas_cmpxformseq_t *pxformseq;
1104 jas_cmreal_t mat[3][4];1243 jas_cmreal_t mat[3][4];
1105 jas_cmshapmatlut_t lut;1244 jas_cmshapmatlut_t lut;
1245 jas_cmshapmatlut_init(&lut);
1106 1246
1107 pxform = 0;1247 pxform = 0;
1108 pxformseq = 0;1248 pxformseq = 0;
@@ -1117,22 +1257,32 @@ static int triclr(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retp · 8 unmodified lines
1117 !(trcs[2] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_BLUTRC)) ||1257 !(trcs[2] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_BLUTRC)) ||
1118 !(cols[0] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_REDMATCOL)) ||1258 !(cols[0] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_REDMATCOL)) ||
1119 !(cols[1] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRNMATCOL)) ||1259 !(cols[1] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRNMATCOL)) ||
1120 !(cols[2] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_BLUMATCOL)))1260 !(cols[2] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_BLUMATCOL))) {
1261 jas_logerrorf("error: unexpected attribute value\n");
1121 goto error;1262 goto error;
1263 }
1122 for (unsigned i = 0; i < 3; ++i) {1264 for (unsigned i = 0; i < 3; ++i) {
1123 if (trcs[i]->type != JAS_ICC_TYPE_CURV ||1265 if (trcs[i]->type != JAS_ICC_TYPE_CURV ||
1124 cols[i]->type != JAS_ICC_TYPE_XYZ)1266 cols[i]->type != JAS_ICC_TYPE_XYZ) {
1267 jas_logerrorf("error: unexpected ICC profile type\n");
1125 goto error;1268 goto error;
1269 }
1126 }1270 }
1127 if (!(pxform = jas_cmpxform_createshapmat()))1271 if (!(pxform = jas_cmpxform_createshapmat())) {
1272 jas_logerrorf("error: jas_cmpxform_createshapmat failed\n");
1128 goto error;1273 goto error;
1274 }
1129 pxform->numinchans = 3;1275 pxform->numinchans = 3;
1130 pxform->numoutchans = 3;1276 pxform->numoutchans = 3;
1131 shapmat = &pxform->data.shapmat;1277 shapmat = &pxform->data.shapmat;
1132 if (!(pxformseq = jas_cmpxformseq_create()))1278 if (!(pxformseq = jas_cmpxformseq_create())) {
1279 jas_logerrorf("error: jas_cmpxformseq_create failed\n");
1133 goto error;1280 goto error;
1134 if (jas_cmpxformseq_insertpxform(pxformseq, -1, pxform))1281 }
1282 if (jas_cmpxformseq_insertpxform(pxformseq, -1, pxform)) {
1283 jas_logerrorf("error: jas_cmpxformseq_insertpxform failed\n");
1135 goto error;1284 goto error;
1285 }
1136 shapmat->mono = 0;1286 shapmat->mono = 0;
1137 shapmat->useluts = 1;1287 shapmat->useluts = 1;
1138 shapmat->usemat = 1;1288 shapmat->usemat = 1;
@@ -1143,11 +1293,14 @@ static int triclr(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retp · 4 unmodified lines
1143 shapmat->mat[1][i] = (jas_cmreal_t)cols[i]->data.xyz.y / 65536.0;1293 shapmat->mat[1][i] = (jas_cmreal_t)cols[i]->data.xyz.y / 65536.0;
1144 shapmat->mat[2][i] = (jas_cmreal_t)cols[i]->data.xyz.z / 65536.0;1294 shapmat->mat[2][i] = (jas_cmreal_t)cols[i]->data.xyz.z / 65536.0;
1145 }1295 }
1146 for (unsigned i = 0; i < 3; ++i)1296 for (unsigned i = 0; i < 3; ++i) {
1147 shapmat->mat[i][3] = 0.0;1297 shapmat->mat[i][3] = 0.0;
1298 }
1148 for (unsigned i = 0; i < 3; ++i) {1299 for (unsigned i = 0; i < 3; ++i) {
1149 if (jas_cmshapmatlut_set(&shapmat->luts[i], &trcs[i]->data.curv))1300 if (jas_cmshapmatlut_set(&shapmat->luts[i], &trcs[i]->data.curv)) {
1301 jas_logerrorf("error: jas_cmshapmatlut_set failed\n");
1150 goto error;1302 goto error;
1303 }
1151 }1304 }
1152 } else {1305 } else {
1153 shapmat->order = 1;1306 shapmat->order = 1;
@@ -1156,16 +1309,23 @@ static int triclr(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retp · 2 unmodified lines
1156 mat[1][i] = (jas_cmreal_t)cols[i]->data.xyz.y / 65536.0;1309 mat[1][i] = (jas_cmreal_t)cols[i]->data.xyz.y / 65536.0;
1157 mat[2][i] = (jas_cmreal_t)cols[i]->data.xyz.z / 65536.0;1310 mat[2][i] = (jas_cmreal_t)cols[i]->data.xyz.z / 65536.0;
1158 }1311 }
1159 for (unsigned i = 0; i < 3; ++i)1312 for (unsigned i = 0; i < 3; ++i) {
1160 mat[i][3] = 0.0;1313 mat[i][3] = 0.0;
1161 if (jas_cmshapmat_invmat(shapmat->mat, mat))1314 }
1315 if (jas_cmshapmat_invmat(shapmat->mat, mat)) {
1316 jas_logerrorf("error: jas_cmshapmat_invmat failed\n");
1162 goto error;1317 goto error;
1318 }
1163 for (unsigned i = 0; i < 3; ++i) {1319 for (unsigned i = 0; i < 3; ++i) {
1164 jas_cmshapmatlut_init(&lut);1320 jas_cmshapmatlut_init(&lut);
1165 if (jas_cmshapmatlut_set(&lut, &trcs[i]->data.curv))1321 if (jas_cmshapmatlut_set(&lut, &trcs[i]->data.curv)) {
1322 jas_logerrorf("error: jas_cmshapmatlut_set failed\n");
1166 goto error;1323 goto error;
1167 if (jas_cmshapmatlut_invert(&shapmat->luts[i], &lut, lut.size))1324 }
1325 if (jas_cmshapmatlut_invert(&shapmat->luts[i], &lut, lut.size)) {
1326 jas_logerrorf("error: jas_cmshapmatlut_invert failed\n");
1168 goto error;1327 goto error;
1328 }
1169 jas_cmshapmatlut_cleanup(&lut);1329 jas_cmshapmatlut_cleanup(&lut);
1170 }1330 }
1171 }1331 }
@@ -1179,6 +1339,7 @@ static int triclr(const jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retp · 7 unmodified lines
1179 1339
1180error:1340error:
1181 1341
1342 jas_cmshapmatlut_cleanup(&lut);
1182 for (unsigned i = 0; i < 3; ++i) {1343 for (unsigned i = 0; i < 3; ++i) {
1183 if (trcs[i]) {1344 if (trcs[i]) {
1184 jas_iccattrval_destroy(trcs[i]);1345 jas_iccattrval_destroy(trcs[i]);
@@ -1204,11 +1365,13 @@ static int jas_cmgetint(const long **bufptr, int sgnd, unsigned prec, long *val) · 19 unmodified lines
1204 v = **bufptr;1365 v = **bufptr;
1205 if (sgnd) {1366 if (sgnd) {
1206 m = (1 << (prec - 1));1367 m = (1 << (prec - 1));
1207 if (v < -m || v >= m)1368 if (v < -m || v >= m) {
1208 return -1;1369 return -1;
1370 }
1209 } else {1371 } else {
1210 if (v < 0 || v >= (1 << prec))1372 if (v < 0 || v >= (1 << prec)) {
1211 return -1;1373 return -1;
1374 }
1212 }1375 }
1213 ++(*bufptr);1376 ++(*bufptr);
1214 *val = v;1377 *val = v;
@@ -1220,11 +1383,13 @@ static int jas_cmputint(long **bufptr, int sgnd, unsigned prec, long val) · 5 unmodified lines
1220 int m;1383 int m;
1221 if (sgnd) {1384 if (sgnd) {
1222 m = (1 << (prec - 1));1385 m = (1 << (prec - 1));
1223 if (val < -m || val >= m)1386 if (val < -m || val >= m) {
1224 return -1;1387 return -1;
1388 }
1225 } else {1389 } else {
1226 if (val < 0 || val >= (1 << prec))1390 if (val < 0 || val >= (1 << prec)) {
1227 return -1;1391 return -1;
1392 }
1228 }1393 }
1229 **bufptr = val;1394 **bufptr = val;
1230 ++(*bufptr);1395 ++(*bufptr);
@@ -1243,8 +1408,8 @@ unsigned jas_clrspc_numchans(jas_clrspc_t clrspc) · 12 unmodified lines
1243 return 1;1408 return 1;
1244 default:1409 default:
1245 abort();1410 abort();
1411 return 0;
1246 }1412 }
1247 return -1;
1248}1413}
1249 1414
1250jas_iccprof_t *jas_iccprof_createfromcmprof(const jas_cmprof_t *prof)1415jas_iccprof_t *jas_iccprof_createfromcmprof(const jas_cmprof_t *prof)
jas_debug.c+183−22
@@ -63,53 +63,214 @@ · 62 unmodified lines
63* Includes.63* Includes.
64\******************************************************************************/64\******************************************************************************/
65 65
66#define JAS_FOR_INTERNAL_USE_ONLY
67
68#include "jasper/jas_init.h"
69#include "jasper/jas_compiler.h"
66#include "jasper/jas_debug.h"70#include "jasper/jas_debug.h"
67#include "jasper/jas_types.h"71#include "jasper/jas_types.h"
72#include "jasper/jas_log.h"
68 73
69/******************************************************************************\74/******************************************************************************\
70* Local data.75* Code for getting/setting the debug level.
71\******************************************************************************/76\******************************************************************************/
72 77
73static int jas_dbglevel = 0;78/* Set the library debug level. */
74/* The debug level. */79JAS_DEPRECATED
80int jas_setdbglevel(int level)
81{
82 jas_deprecated("jas_setdbglevel is deprecated\n");
83 int old_level = jas_get_debug_level();
84 jas_set_debug_level(level);
85 return old_level;
86}
75 87
76/******************************************************************************\88/******************************************************************************\
77* Code for getting/setting the debug level.89* Code.
78\******************************************************************************/90\******************************************************************************/
79 91
80/* Set the library debug level. */92/* Perform formatted output to standard error. */
81int jas_setdbglevel(int dbglevel)93int jas_eprintf(const char *fmt, ...)
82{94{
83 int olddbglevel;95 int ret;
96 va_list ap;
97 va_start(ap, fmt);
98 ret = vfprintf(stderr, fmt, ap);
99 va_end(ap);
100 return ret;
101}
84 102
85 /* Save the old debug level. */103/* Generate formatted error log message. */
86 olddbglevel = jas_dbglevel;104int jas_logprintf(const char *fmt, ...)
105{
106 int ret;
107 va_list ap;
108 va_start(ap, fmt);
109 ret = jas_vlogmsgf(jas_logtype_init(JAS_LOGTYPE_CLASS_NULL, 0), fmt,
110 ap);
111 va_end(ap);
112 return ret;
113}
87 114
88 /* Change the debug level. */115/* Generate formatted error log message. */
89 jas_dbglevel = dbglevel;116int jas_logerrorf(const char *fmt, ...)
117{
118 int ret;
119 va_list ap;
120 va_start(ap, fmt);
121 ret = jas_vlogmsgf(jas_logtype_init(JAS_LOGTYPE_CLASS_ERROR, 0), fmt,
122 ap);
123 va_end(ap);
124 return ret;
125}
90 126
91 /* Return the old debug level. */127/* Generate formatted warning log message. */
92 return olddbglevel;128int jas_logwarnf(const char *fmt, ...)
129{
130 int ret;
131 va_list ap;
132 va_start(ap, fmt);
133 ret = jas_vlogmsgf(jas_logtype_init(JAS_LOGTYPE_CLASS_WARN, 0), fmt,
134 ap);
135 va_end(ap);
136 return ret;
93}137}
94 138
95/* Get the library debug level. */139/* Generate formatted informational log message. */
96int jas_getdbglevel()140int jas_loginfof(const char *fmt, ...)
97{141{
98 return jas_dbglevel;142 int ret;
143 va_list ap;
144 va_start(ap, fmt);
145 ret = jas_vlogmsgf(jas_logtype_init(JAS_LOGTYPE_CLASS_INFO, 0), fmt,
146 ap);
147 va_end(ap);
148 return ret;
149}
150
151/* Generate formatted debugging log message. */
152int jas_logdebugf(int priority, const char *fmt, ...)
153{
154 int ret;
155 va_list ap;
156 va_start(ap, fmt);
157 ret = jas_vlogmsgf(jas_logtype_init(JAS_LOGTYPE_CLASS_DEBUG, priority),
158 fmt, ap);
159 va_end(ap);
160 return ret;
161}
162
163/*!
164@brief
165@details
166*/
167JAS_EXPORT
168int jas_vlogmsgf(jas_logtype_t type, const char *fmt, va_list ap)
169{
170 int ret;
171 jas_vlogmsgf_t *func = jas_get_vlogmsgf();
172 ret = func(type, fmt, ap);
173 return ret;
174}
175
176/* Perform formatted output to standard error. */
177JAS_EXPORT
178int jas_vlogmsgf_stderr(jas_logtype_t type, const char *fmt, va_list ap)
179{
180#if 1
181 JAS_UNUSED(type);
182 int result = vfprintf(stderr, fmt, ap);
183 return result;
184#else
185 const char *s = "INVALID";
186 switch (jas_logtype_getclass(type)) {
187 case JAS_LOGTYPE_CLASS_NULL:
188 s = "OTHER";
189 break;
190 case JAS_LOGTYPE_CLASS_ERROR:
191 s = "ERROR";
192 break;
193 case JAS_LOGTYPE_CLASS_WARN:
194 s = "WARNING";
195 break;
196 case JAS_LOGTYPE_CLASS_INFO:
197 s = "INFO";
198 break;
199 case JAS_LOGTYPE_CLASS_DEBUG:
200 s = "DEBUG";
201 break;
202 }
203 int r1 = fprintf(stderr, "%s: ", s);
204 int r2 = vfprintf(stderr, fmt, ap);
205 int result = -1;
206 if (r1 > 0 && r2 > 0) {
207 result = r1 + r2;
208 }
209 return result;
210#endif
211}
212
213/* Perform formatted output to standard error. */
214JAS_EXPORT
215int jas_vlogmsgf_discard(jas_logtype_t type, const char *fmt, va_list ap)
216{
217 JAS_UNUSED(type);
218 JAS_CAST(void, fmt);
219 JAS_CAST(void, ap);
220 return 0;
221}
222
223/* Dump memory to a stream. */
224int jas_memdump(FILE *out, const void *data, size_t len)
225{
226 size_t i;
227 size_t j;
228 const jas_uchar *dp = data;
229 for (i = 0; i < len; i += 16) {
230 fprintf(out, "%04zx:", i);
231 for (j = 0; j < 16; ++j) {
232 if (i + j < len) {
233 fprintf(out, " %02x", dp[i + j]);
234 }
235 }
236 fprintf(out, "\n");
237 }
238 return 0;
239}
240
241/* Dump memory to a stream. */
242int jas_logmemdump(const void *data, size_t len)
243{
244 size_t i;
245 size_t j;
246 const jas_uchar *dp = data;
247 for (i = 0; i < len; i += 16) {
248 jas_logprintf("%04zx:", i);
249 for (j = 0; j < 16; ++j) {
250 if (i + j < len) {
251 jas_logprintf(" %02x", dp[i + j]);
252 }
253 }
254 jas_logprintf("\n");
255 }
256 return 0;
99}257}
100 258
101/******************************************************************************\259/******************************************************************************\
102* Code.260* Code.
103\******************************************************************************/261\******************************************************************************/
104 262
105/* Perform formatted output to standard error. */263void jas_deprecated(const char *fmt, ...)
106int jas_eprintf(const char *fmt, ...)
107{264{
108 int ret;265 static const char message[] =
266 "WARNING: YOUR CODE IS RELYING ON DEPRECATED FUNCTIONALITY IN THE JASPER\n"
267 "LIBRARY. THIS FUNCTIONALITY WILL BE REMOVED IN THE NEAR FUTURE. PLEASE\n"
268 "FIX THIS PROBLEM BEFORE YOUR CODE STOPS WORKING.\n"
269 ;
270 fprintf(stderr, "%s", message);
271 fprintf(stderr, "deprecation warning: ");
109 va_list ap;272 va_list ap;
110
111 va_start(ap, fmt);273 va_start(ap, fmt);
112 ret = vfprint(2, fmt, ap);274 vfprintf(stderr, fmt, ap);
113 va_end(ap);275 va_end(ap);
114 return ret;
115}276}
jas_icc.c+435−239
@@ -59,12 +59,23 @@ · 58 unmodified lines
59 * __END_OF_JASPER_LICENSE__59 * __END_OF_JASPER_LICENSE__
60 */60 */
61 61
62/******************************************************************************\
63* Includes.
64\******************************************************************************/
65
66#define JAS_FOR_INTERNAL_USE_ONLY
67
62#include "jasper/jas_icc.h"68#include "jasper/jas_icc.h"
63#include "jasper/jas_types.h"69#include "jasper/jas_types.h"
64#include "jasper/jas_malloc.h"70#include "jasper/jas_malloc.h"
65#include "jasper/jas_debug.h"71#include "jasper/jas_debug.h"
66#include "jasper/jas_cm.h"72#include "jasper/jas_cm.h"
67#include "jasper/jas_stream.h"73#include "jasper/jas_stream.h"
74#include "jasper/jas_string.h"
75
76/******************************************************************************\
77*
78\******************************************************************************/
68 79
69#define jas_iccputuint8(out, val) jas_iccputuint(out, 1, val)80#define jas_iccputuint8(out, val) jas_iccputuint(out, 1, val)
70#define jas_iccputuint16(out, val) jas_iccputuint(out, 2, val)81#define jas_iccputuint16(out, val) jas_iccputuint(out, 2, val)
@@ -80,15 +91,11 @@ static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val); · 9 unmodified lines
80static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val);91static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val);
81static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val);92static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val);
82static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val);93static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val);
83//#ifdef JAS_ENABLE_ENCODER
84static int jas_iccputuint(jas_stream_t *out, unsigned n, jas_ulonglong val);94static int jas_iccputuint(jas_stream_t *out, unsigned n, jas_ulonglong val);
85static int jas_iccputsint(jas_stream_t *out, unsigned n, jas_longlong val);95static int jas_iccputsint(jas_stream_t *out, unsigned n, jas_longlong val);
86//#endif /* JAS_ENABLE_ENCODER */
87static jas_iccprof_t *jas_iccprof_create(void);96static jas_iccprof_t *jas_iccprof_create(void);
88static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr);97static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr);
89//#ifdef JAS_ENABLE_ENCODER
90static int jas_iccprof_writehdr(jas_stream_t *out, const jas_icchdr_t *hdr);98static int jas_iccprof_writehdr(jas_stream_t *out, const jas_icchdr_t *hdr);
91//#endif
92static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab);99static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab);
93static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab);100static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab);
94static int jas_iccattrtab_lookup(const jas_iccattrtab_t *attrtab, jas_iccuint32_t name);101static int jas_iccattrtab_lookup(const jas_iccattrtab_t *attrtab, jas_iccuint32_t name);
@@ -104,9 +111,8 @@ static int jas_icccurv_copy(jas_iccattrval_t *attrval, · 9 unmodified lines
104static int jas_icccurv_input(jas_iccattrval_t *attrval, jas_stream_t *in,111static int jas_icccurv_input(jas_iccattrval_t *attrval, jas_stream_t *in,
105 unsigned cnt);112 unsigned cnt);
106static unsigned jas_icccurv_getsize(const jas_iccattrval_t *attrval);113static unsigned jas_icccurv_getsize(const jas_iccattrval_t *attrval);
107//#ifdef JAS_ENABLE_ENCODER
108static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out);114static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out);
109//#endif115static void jas_icccurv_dump(const jas_iccattrval_t *attrval, FILE *out);
110 116
111static void jas_icctxtdesc_destroy(jas_iccattrval_t *attrval);117static void jas_icctxtdesc_destroy(jas_iccattrval_t *attrval);
112static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval,118static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval,
@@ -114,9 +120,8 @@ static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval, · 1 unmodified line
114static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in,120static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in,
115 unsigned cnt);121 unsigned cnt);
116static unsigned jas_icctxtdesc_getsize(const jas_iccattrval_t *attrval);122static unsigned jas_icctxtdesc_getsize(const jas_iccattrval_t *attrval);
117//#ifdef JAS_ENABLE_ENCODER
118static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out);123static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out);
119//#endif124static void jas_icctxtdesc_dump(const jas_iccattrval_t *attrval, FILE *out);
120 125
121static void jas_icctxt_destroy(jas_iccattrval_t *attrval);126static void jas_icctxt_destroy(jas_iccattrval_t *attrval);
122static int jas_icctxt_copy(jas_iccattrval_t *attrval,127static int jas_icctxt_copy(jas_iccattrval_t *attrval,
@@ -124,16 +129,14 @@ static int jas_icctxt_copy(jas_iccattrval_t *attrval, · 1 unmodified line
124static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in,129static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in,
125 unsigned cnt);130 unsigned cnt);
126static unsigned jas_icctxt_getsize(const jas_iccattrval_t *attrval);131static unsigned jas_icctxt_getsize(const jas_iccattrval_t *attrval);
127//#ifdef JAS_ENABLE_ENCODER
128static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out);132static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out);
129//#endif133static void jas_icctxt_dump(const jas_iccattrval_t *attrval, FILE *out);
130 134
131static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in,135static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in,
132 unsigned cnt);136 unsigned cnt);
133static unsigned jas_iccxyz_getsize(const jas_iccattrval_t *attrval);137static unsigned jas_iccxyz_getsize(const jas_iccattrval_t *attrval);
134//#ifdef JAS_ENABLE_ENCODER
135static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out);138static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out);
136//#endif139static void jas_iccxyz_dump(const jas_iccattrval_t *attrval, FILE *out);
137 140
138static jas_iccattrtab_t *jas_iccattrtab_create(void);141static jas_iccattrtab_t *jas_iccattrtab_create(void);
139static void jas_iccattrtab_destroy(jas_iccattrtab_t *tab);142static void jas_iccattrtab_destroy(jas_iccattrtab_t *tab);
@@ -143,12 +146,10 @@ static int jas_iccattrtab_add(jas_iccattrtab_t *attrtab, int i, · 3 unmodified lines
143static int jas_iccattrtab_replace(jas_iccattrtab_t *attrtab, unsigned i,146static int jas_iccattrtab_replace(jas_iccattrtab_t *attrtab, unsigned i,
144 jas_iccuint32_t name, jas_iccattrval_t *val);147 jas_iccuint32_t name, jas_iccattrval_t *val);
145static void jas_iccattrtab_delete(jas_iccattrtab_t *attrtab, unsigned i);148static void jas_iccattrtab_delete(jas_iccattrtab_t *attrtab, unsigned i);
146//#ifdef JAS_ENABLE_ENCODER
147static unsigned jas_iccpadtomult(unsigned x, unsigned y);149static unsigned jas_iccpadtomult(unsigned x, unsigned y);
148static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, unsigned i,150static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, unsigned i,
149 jas_iccattrname_t *name, jas_iccattrval_t **val);151 jas_iccattrname_t *name, jas_iccattrval_t **val);
150static int jas_iccprof_puttagtab(jas_stream_t *out, const jas_icctagtab_t *tagtab);152static int jas_iccprof_puttagtab(jas_stream_t *out, const jas_icctagtab_t *tagtab);
151//#endif /* JAS_ENABLE_ENCODER */
152 153
153static void jas_icclut16_destroy(jas_iccattrval_t *attrval);154static void jas_icclut16_destroy(jas_iccattrval_t *attrval);
154static int jas_icclut16_copy(jas_iccattrval_t *attrval,155static int jas_icclut16_copy(jas_iccattrval_t *attrval,
@@ -156,9 +157,8 @@ static int jas_icclut16_copy(jas_iccattrval_t *attrval, · 1 unmodified line
156static int jas_icclut16_input(jas_iccattrval_t *attrval, jas_stream_t *in,157static int jas_icclut16_input(jas_iccattrval_t *attrval, jas_stream_t *in,
157 unsigned cnt);158 unsigned cnt);
158static unsigned jas_icclut16_getsize(const jas_iccattrval_t *attrval);159static unsigned jas_icclut16_getsize(const jas_iccattrval_t *attrval);
159//#ifdef JAS_ENABLE_ENCODER
160static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out);160static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out);
161//#endif161static void jas_icclut16_dump(const jas_iccattrval_t *attrval, FILE *out);
162 162
163static void jas_icclut8_destroy(jas_iccattrval_t *attrval);163static void jas_icclut8_destroy(jas_iccattrval_t *attrval);
164static int jas_icclut8_copy(jas_iccattrval_t *attrval,164static int jas_icclut8_copy(jas_iccattrval_t *attrval,
@@ -166,19 +166,19 @@ static int jas_icclut8_copy(jas_iccattrval_t *attrval, · 1 unmodified line
166static int jas_icclut8_input(jas_iccattrval_t *attrval, jas_stream_t *in,166static int jas_icclut8_input(jas_iccattrval_t *attrval, jas_stream_t *in,
167 unsigned cnt);167 unsigned cnt);
168static unsigned jas_icclut8_getsize(const jas_iccattrval_t *attrval);168static unsigned jas_icclut8_getsize(const jas_iccattrval_t *attrval);
169//#ifdef JAS_ENABLE_ENCODER
170static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out);169static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out);
171//#endif /* JAS_ENABLE_ENCODER */170static void jas_icclut8_dump(const jas_iccattrval_t *attrval, FILE *out);
172 171
173//#ifdef JAS_ENABLE_ENCODER
174static int jas_iccputtime(jas_stream_t *out, const jas_icctime_t *ctime);172static int jas_iccputtime(jas_stream_t *out, const jas_icctime_t *ctime);
175static int jas_iccputxyz(jas_stream_t *out, const jas_iccxyz_t *xyz);173static int jas_iccputxyz(jas_stream_t *out, const jas_iccxyz_t *xyz);
176//#endif /* JAS_ENABLE_ENCODER */
177 174
178static unsigned jas_iccpowi(unsigned x, unsigned n);175static unsigned jas_iccpowi(unsigned x, unsigned n);
179 176
180static char *jas_iccsigtostr(unsigned sig, char *buf);177static char *jas_iccsigtostr(unsigned sig, char *buf);
181 178
179/******************************************************************************\
180* Data.
181\******************************************************************************/
182 182
183static const jas_iccattrvalinfo_t jas_iccattrvalinfos[] = {183static const jas_iccattrvalinfo_t jas_iccattrvalinfos[] = {
184 {184 {
@@ -186,10 +186,9 @@ static const jas_iccattrvalinfo_t jas_iccattrvalinfos[] = { · 1 unmodified line
186 jas_icccurv_destroy,186 jas_icccurv_destroy,
187 jas_icccurv_copy,187 jas_icccurv_copy,
188 jas_icccurv_input,188 jas_icccurv_input,
189//#ifdef JAS_ENABLE_ENCODER
190 jas_icccurv_output,189 jas_icccurv_output,
191//#endif
192 jas_icccurv_getsize,190 jas_icccurv_getsize,
191 jas_icccurv_dump,
193 },192 },
194 },193 },
195 {194 {
@@ -198,10 +197,9 @@ static const jas_iccattrvalinfo_t jas_iccattrvalinfos[] = { · 2 unmodified lines
198 0,197 0,
199 0,198 0,
200 jas_iccxyz_input,199 jas_iccxyz_input,
201//#ifdef JAS_ENABLE_ENCODER
202 jas_iccxyz_output,200 jas_iccxyz_output,
203//#endif
204 jas_iccxyz_getsize,201 jas_iccxyz_getsize,
202 jas_iccxyz_dump,
205 },203 },
206 },204 },
207 {205 {
@@ -210,10 +208,9 @@ static const jas_iccattrvalinfo_t jas_iccattrvalinfos[] = { · 2 unmodified lines
210 jas_icctxtdesc_destroy,208 jas_icctxtdesc_destroy,
211 jas_icctxtdesc_copy,209 jas_icctxtdesc_copy,
212 jas_icctxtdesc_input,210 jas_icctxtdesc_input,
213//#ifdef JAS_ENABLE_ENCODER
214 jas_icctxtdesc_output,211 jas_icctxtdesc_output,
215//#endif
216 jas_icctxtdesc_getsize,212 jas_icctxtdesc_getsize,
213 jas_icctxtdesc_dump,
217 },214 },
218 },215 },
219 {216 {
@@ -222,10 +219,9 @@ static const jas_iccattrvalinfo_t jas_iccattrvalinfos[] = { · 2 unmodified lines
222 jas_icctxt_destroy,219 jas_icctxt_destroy,
223 jas_icctxt_copy,220 jas_icctxt_copy,
224 jas_icctxt_input,221 jas_icctxt_input,
225//#ifdef JAS_ENABLE_ENCODER
226 jas_icctxt_output,222 jas_icctxt_output,
227//#endif
228 jas_icctxt_getsize,223 jas_icctxt_getsize,
224 jas_icctxt_dump,
229 },225 },
230 },226 },
231 {227 {
@@ -234,10 +230,9 @@ static const jas_iccattrvalinfo_t jas_iccattrvalinfos[] = { · 2 unmodified lines
234 jas_icclut8_destroy,230 jas_icclut8_destroy,
235 jas_icclut8_copy,231 jas_icclut8_copy,
236 jas_icclut8_input,232 jas_icclut8_input,
237//#ifdef JAS_ENABLE_ENCODER
238 jas_icclut8_output,233 jas_icclut8_output,
239//#endif
240 jas_icclut8_getsize,234 jas_icclut8_getsize,
235 jas_icclut8_dump,
241 },236 },
242 },237 },
243 {238 {
@@ -245,10 +240,9 @@ static const jas_iccattrvalinfo_t jas_iccattrvalinfos[] = { · 1 unmodified line
245 jas_icclut16_destroy,240 jas_icclut16_destroy,
246 jas_icclut16_copy,241 jas_icclut16_copy,
247 jas_icclut16_input,242 jas_icclut16_input,
248//#ifdef JAS_ENABLE_ENCODER
249 jas_icclut16_output,243 jas_icclut16_output,
250//#endif
251 jas_icclut16_getsize,244 jas_icclut16_getsize,
245 jas_icclut16_dump,
252 },246 },
253 },247 },
254 {248 {
@@ -257,9 +251,8 @@ static const jas_iccattrvalinfo_t jas_iccattrvalinfos[] = { · 2 unmodified lines
257 0,251 0,
258 0,252 0,
259 0,253 0,
260//#ifdef JAS_ENABLE_ENCODER
261 0,254 0,
262//#endif255 0,
263 0,256 0,
264 },257 },
265 }258 }
@@ -275,46 +268,58 @@ static jas_iccprof_t *jas_iccprof_create() · 9 unmodified lines
275 if (!(prof = jas_malloc(sizeof(jas_iccprof_t)))) {268 if (!(prof = jas_malloc(sizeof(jas_iccprof_t)))) {
276 goto error;269 goto error;
277 }270 }
278 if (!(prof->attrtab = jas_iccattrtab_create()))
279 goto error;
280 memset(&prof->hdr, 0, sizeof(jas_icchdr_t));
281 prof->tagtab.numents = 0;271 prof->tagtab.numents = 0;
282 prof->tagtab.ents = 0;272 prof->tagtab.ents = 0;
273 if (!(prof->attrtab = jas_iccattrtab_create())) {
274 goto error;
275 }
276 memset(&prof->hdr, 0, sizeof(jas_icchdr_t));
283 return prof;277 return prof;
284error:278error:
285 if (prof)279 if (prof) {
286 jas_iccprof_destroy(prof);280 jas_iccprof_destroy(prof);
281 }
287 return 0;282 return 0;
288}283}
289 284
290jas_iccprof_t *jas_iccprof_copy(const jas_iccprof_t *prof)285jas_iccprof_t *jas_iccprof_copy(const jas_iccprof_t *prof)
291{286{
292 jas_iccprof_t *newprof;287 jas_iccprof_t *newprof;
293 if (!(newprof = jas_iccprof_create()))288 if (!(newprof = jas_iccprof_create())) {
294 goto error;289 goto error;
290 }
295 newprof->hdr = prof->hdr;291 newprof->hdr = prof->hdr;
296 newprof->tagtab.numents = 0;292 newprof->tagtab.numents = 0;
297 newprof->tagtab.ents = 0;293 newprof->tagtab.ents = 0;
298 assert(newprof->attrtab);294 assert(newprof->attrtab);
299 jas_iccattrtab_destroy(newprof->attrtab);295 jas_iccattrtab_destroy(newprof->attrtab);
300 if (!(newprof->attrtab = jas_iccattrtab_copy(prof->attrtab)))296 if (!(newprof->attrtab = jas_iccattrtab_copy(prof->attrtab))) {
301 goto error;297 goto error;
298 }
302 return newprof;299 return newprof;
303error:300error:
304 if (newprof)301 if (newprof) {
305 jas_iccprof_destroy(newprof);302 jas_iccprof_destroy(newprof);
303 }
306 return 0;304 return 0;
307}305}
308 306
309void jas_iccprof_destroy(jas_iccprof_t *prof)307void jas_iccprof_destroy(jas_iccprof_t *prof)
310{308{
311 if (prof->attrtab)309 if (prof->attrtab) {
312 jas_iccattrtab_destroy(prof->attrtab);310 jas_iccattrtab_destroy(prof->attrtab);
313 if (prof->tagtab.ents)311 }
312 if (prof->tagtab.ents) {
314 jas_free(prof->tagtab.ents);313 jas_free(prof->tagtab.ents);
314 }
315 jas_free(prof);315 jas_free(prof);
316}316}
317 317
318void jas_iccprof_dump(const jas_iccprof_t *prof, FILE *out)
319{
320 jas_iccattrtab_dump(prof->attrtab, out);
321}
322
318jas_iccprof_t *jas_iccprof_load(jas_stream_t *in)323jas_iccprof_t *jas_iccprof_load(jas_stream_t *in)
319{324{
320 jas_iccprof_t *prof;325 jas_iccprof_t *prof;
@@ -332,11 +337,11 @@ jas_iccprof_t *jas_iccprof_load(jas_stream_t *in) · 11 unmodified lines
332 }337 }
333 338
334 if (jas_iccprof_readhdr(in, &prof->hdr)) {339 if (jas_iccprof_readhdr(in, &prof->hdr)) {
335 jas_eprintf("cannot get header\n");340 jas_logerrorf("cannot get header\n");
336 goto error;341 goto error;
337 }342 }
338 if (jas_iccprof_gettagtab(in, &prof->tagtab)) {343 if (jas_iccprof_gettagtab(in, &prof->tagtab)) {
339 jas_eprintf("cannot get tab table\n");344 jas_logerrorf("cannot get tab table\n");
340 goto error;345 goto error;
341 }346 }
342 jas_iccprof_sorttagtab(&prof->tagtab);347 jas_iccprof_sorttagtab(&prof->tagtab);
@@ -349,23 +354,24 @@ jas_iccprof_t *jas_iccprof_load(jas_stream_t *in) · 6 unmodified lines
349 const jas_icctagtabent_t *tagtabent = &prof->tagtab.ents[i];354 const jas_icctagtabent_t *tagtabent = &prof->tagtab.ents[i];
350 if (tagtabent->off == JAS_CAST(jas_iccuint32_t, prevoff)) {355 if (tagtabent->off == JAS_CAST(jas_iccuint32_t, prevoff)) {
351 if (prevattrval) {356 if (prevattrval) {
352 if (!(attrval = jas_iccattrval_clone(prevattrval)))357 if (!(attrval = jas_iccattrval_clone(prevattrval))) {
353 goto error;358 goto error;
354 if (jas_iccprof_setattr(prof, tagtabent->tag, attrval))359 }
360 if (jas_iccprof_setattr(prof, tagtabent->tag, attrval)) {
355 goto error;361 goto error;
362 }
356 jas_iccattrval_destroy(attrval);363 jas_iccattrval_destroy(attrval);
357 attrval = 0;364 attrval = 0;
358 } else {365 } else {
359#if 0366 jas_logwarnf("warning: skipping unknown tag type\n");
360 jas_eprintf("warning: skipping unknown tag type\n");
361#endif
362 }367 }
363 continue;368 continue;
364 }369 }
365 reloff = tagtabent->off - curoff;370 reloff = tagtabent->off - curoff;
366 if (reloff > 0) {371 if (reloff > 0) {
367 if (jas_stream_gobble(in, reloff) != reloff)372 if (jas_stream_gobble(in, reloff) != reloff) {
368 goto error;373 goto error;
374 }
369 curoff += reloff;375 curoff += reloff;
370 } else if (reloff < 0) {376 } else if (reloff < 0) {
371 goto error;377 goto error;
@@ -379,9 +385,7 @@ jas_iccprof_t *jas_iccprof_load(jas_stream_t *in) · 7 unmodified lines
379 }385 }
380 curoff += 8;386 curoff += 8;
381 if (!jas_iccattrvalinfo_lookup(type)) {387 if (!jas_iccattrvalinfo_lookup(type)) {
382#if 0388 jas_logwarnf("warning: skipping unknown tag type\n");
383 jas_eprintf("warning: skipping unknown tag type\n");
384#endif
385 prevattrval = 0;389 prevattrval = 0;
386 continue;390 continue;
387 }391 }
@@ -404,16 +408,17 @@ jas_iccprof_t *jas_iccprof_load(jas_stream_t *in) · 16 unmodified lines
404 return prof;408 return prof;
405 409
406error:410error:
407 if (prof)411 if (prof) {
408 jas_iccprof_destroy(prof);412 jas_iccprof_destroy(prof);
409 if (attrval)413 }
414 if (attrval) {
410 jas_iccattrval_destroy(attrval);415 jas_iccattrval_destroy(attrval);
416 }
411 return 0;417 return 0;
412}418}
413 419
414int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out)420int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out)
415{421{
416//#ifdef JAS_ENABLE_ENCODER
417 long curoff;422 long curoff;
418 long reloff;423 long reloff;
419 long newoff;424 long newoff;
@@ -426,14 +431,16 @@ int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out) · 6 unmodified lines
426 431
427 tagtab = &prof->tagtab;432 tagtab = &prof->tagtab;
428 if (!(tagtab->ents = jas_alloc2(prof->attrtab->numattrs,433 if (!(tagtab->ents = jas_alloc2(prof->attrtab->numattrs,
429 sizeof(jas_icctagtabent_t))))434 sizeof(jas_icctagtabent_t)))) {
430 goto error;435 goto error;
436 }
431 tagtab->numents = prof->attrtab->numattrs;437 tagtab->numents = prof->attrtab->numattrs;
432 curoff = JAS_ICC_HDRLEN + 4 + 12 * tagtab->numents;438 curoff = JAS_ICC_HDRLEN + 4 + 12 * tagtab->numents;
433 for (unsigned i = 0; i < tagtab->numents; ++i) {439 for (unsigned i = 0; i < tagtab->numents; ++i) {
434 tagtabent = &tagtab->ents[i];440 tagtabent = &tagtab->ents[i];
435 if (jas_iccattrtab_get(prof->attrtab, i, &attrname, &attrval))441 if (jas_iccattrtab_get(prof->attrtab, i, &attrname, &attrval)) {
436 goto error;442 goto error;
443 }
437 assert(attrval->ops->output);444 assert(attrval->ops->output);
438 tagtabent->tag = attrname;445 tagtabent->tag = attrname;
439 tagtabent->data = &attrval->data;446 tagtabent->data = &attrval->data;
@@ -462,49 +469,49 @@ int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out) · 22 unmodified lines
462 jas_iccattrval_destroy(attrval);469 jas_iccattrval_destroy(attrval);
463 }470 }
464 prof->hdr.size = curoff;471 prof->hdr.size = curoff;
465 if (jas_iccprof_writehdr(out, &prof->hdr))472 if (jas_iccprof_writehdr(out, &prof->hdr)) {
466 goto error;473 goto error;
467 if (jas_iccprof_puttagtab(out, &prof->tagtab))474 }
475 if (jas_iccprof_puttagtab(out, &prof->tagtab)) {
468 goto error;476 goto error;
477 }
469 curoff = JAS_ICC_HDRLEN + 4 + 12 * tagtab->numents;478 curoff = JAS_ICC_HDRLEN + 4 + 12 * tagtab->numents;
470 for (unsigned i = 0; i < tagtab->numents;) {479 for (unsigned i = 0; i < tagtab->numents;) {
471 tagtabent = &tagtab->ents[i];480 tagtabent = &tagtab->ents[i];
472 assert(curoff == JAS_CAST(long, tagtabent->off));481 assert(curoff == JAS_CAST(long, tagtabent->off));
473 if (jas_iccattrtab_get(prof->attrtab, i, &attrname, &attrval))482 if (jas_iccattrtab_get(prof->attrtab, i, &attrname, &attrval)) {
474 goto error;483 goto error;
484 }
475 if (jas_iccputuint32(out, attrval->type) || jas_stream_pad(out,485 if (jas_iccputuint32(out, attrval->type) || jas_stream_pad(out,
476 4, 0) != 4)486 4, 0) != 4) {
477 goto error;487 goto error;
478 if ((*attrval->ops->output)(attrval, out))488 }
489 if ((*attrval->ops->output)(attrval, out)) {
479 goto error;490 goto error;
491 }
480 jas_iccattrval_destroy(attrval);492 jas_iccattrval_destroy(attrval);
481 curoff += tagtabent->len;493 curoff += tagtabent->len;
482 ++i;494 ++i;
483 while (i < tagtab->numents &&495 while (i < tagtab->numents && tagtab->ents[i].first) {
484 tagtab->ents[i].first)
485 ++i;496 ++i;
497 }
486 newoff = (i < tagtab->numents) ?498 newoff = (i < tagtab->numents) ?
487 tagtab->ents[i].off : prof->hdr.size;499 tagtab->ents[i].off : prof->hdr.size;
488 reloff = newoff - curoff;500 reloff = newoff - curoff;
489 assert(reloff >= 0);501 assert(reloff >= 0);
490 if (reloff > 0) {502 if (reloff > 0) {
491 if (jas_stream_pad(out, reloff, 0) != reloff)503 if (jas_stream_pad(out, reloff, 0) != reloff) {
492 goto error;504 goto error;
505 }
493 curoff += reloff;506 curoff += reloff;
494 }507 }
495 } 508 }
496 return 0;509 return 0;
497error:510error:
498 /* XXX - need to free some resources here */511 /* XXX - need to free some resources here */
499//#else
500// (void)prof;
501// (void)out;
502//#endif /* JAS_ENABLE_ENCODER */
503 return -1;512 return -1;
504}513}
505 514
506//#ifdef JAS_ENABLE_ENCODER
507
508static int jas_iccprof_writehdr(jas_stream_t *out, const jas_icchdr_t *hdr)515static int jas_iccprof_writehdr(jas_stream_t *out, const jas_icchdr_t *hdr)
509{516{
510 if (jas_iccputuint32(out, hdr->size) ||517 if (jas_iccputuint32(out, hdr->size) ||
@@ -523,30 +530,31 @@ static int jas_iccprof_writehdr(jas_stream_t *out, const jas_icchdr_t *hdr) · 12 unmodified lines
523 jas_iccputuint32(out, hdr->intent) ||530 jas_iccputuint32(out, hdr->intent) ||
524 jas_iccputxyz(out, &hdr->illum) ||531 jas_iccputxyz(out, &hdr->illum) ||
525 jas_iccputuint32(out, hdr->creator) ||532 jas_iccputuint32(out, hdr->creator) ||
526 jas_stream_pad(out, 44, 0) != 44)533 jas_stream_pad(out, 44, 0) != 44) {
527 return -1;534 return -1;
535 }
528 return 0;536 return 0;
529}537}
530 538
531static int jas_iccprof_puttagtab(jas_stream_t *out, const jas_icctagtab_t *tagtab)539static int jas_iccprof_puttagtab(jas_stream_t *out, const jas_icctagtab_t *tagtab)
532{540{
533 jas_icctagtabent_t *tagtabent;541 jas_icctagtabent_t *tagtabent;
534 if (jas_iccputuint32(out, tagtab->numents))542 if (jas_iccputuint32(out, tagtab->numents)) {
535 goto error;543 goto error;
544 }
536 for (unsigned i = 0; i < tagtab->numents; ++i) {545 for (unsigned i = 0; i < tagtab->numents; ++i) {
537 tagtabent = &tagtab->ents[i];546 tagtabent = &tagtab->ents[i];
538 if (jas_iccputuint32(out, tagtabent->tag) ||547 if (jas_iccputuint32(out, tagtabent->tag) ||
539 jas_iccputuint32(out, tagtabent->off) ||548 jas_iccputuint32(out, tagtabent->off) ||
540 jas_iccputuint32(out, tagtabent->len))549 jas_iccputuint32(out, tagtabent->len)) {
541 goto error;550 goto error;
551 }
542 }552 }
543 return 0;553 return 0;
544error:554error:
545 return -1;555 return -1;
546}556}
547 557
548//#endif
549
550static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr)558static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr)
551{559{
552 if (jas_iccgetuint32(in, &hdr->size) ||560 if (jas_iccgetuint32(in, &hdr->size) ||
@@ -565,8 +573,9 @@ static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr) · 12 unmodified lines
565 jas_iccgetuint32(in, &hdr->intent) ||573 jas_iccgetuint32(in, &hdr->intent) ||
566 jas_iccgetxyz(in, &hdr->illum) ||574 jas_iccgetxyz(in, &hdr->illum) ||
567 jas_iccgetuint32(in, &hdr->creator) ||575 jas_iccgetuint32(in, &hdr->creator) ||
568 jas_stream_gobble(in, 44) != 44)576 jas_stream_gobble(in, 44) != 44) {
569 return -1;577 return -1;
578 }
570 return 0;579 return 0;
571}580}
572 581
@@ -578,17 +587,20 @@ static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab) · 5 unmodified lines
578 jas_free(tagtab->ents);587 jas_free(tagtab->ents);
579 tagtab->ents = 0;588 tagtab->ents = 0;
580 }589 }
581 if (jas_iccgetuint32(in, &tagtab->numents))590 if (jas_iccgetuint32(in, &tagtab->numents)) {
582 goto error;591 goto error;
592 }
583 if (!(tagtab->ents = jas_alloc2(tagtab->numents,593 if (!(tagtab->ents = jas_alloc2(tagtab->numents,
584 sizeof(jas_icctagtabent_t))))594 sizeof(jas_icctagtabent_t)))) {
585 goto error;595 goto error;
596 }
586 tagtabent = tagtab->ents;597 tagtabent = tagtab->ents;
587 for (unsigned i = 0; i < tagtab->numents; ++i) {598 for (unsigned i = 0; i < tagtab->numents; ++i) {
588 if (jas_iccgetuint32(in, &tagtabent->tag) ||599 if (jas_iccgetuint32(in, &tagtabent->tag) ||
589 jas_iccgetuint32(in, &tagtabent->off) ||600 jas_iccgetuint32(in, &tagtabent->off) ||
590 jas_iccgetuint32(in, &tagtabent->len))601 jas_iccgetuint32(in, &tagtabent->len)) {
591 goto error;602 goto error;
603 }
592 ++tagtabent;604 ++tagtabent;
593 }605 }
594 return 0;606 return 0;
@@ -605,10 +617,12 @@ jas_iccattrval_t *jas_iccprof_getattr(const jas_iccprof_t *prof, · 10 unmodified lines
605{617{
606 int i;618 int i;
607 jas_iccattrval_t *attrval;619 jas_iccattrval_t *attrval;
608 if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) < 0)620 if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) < 0) {
609 goto error;621 goto error;
610 if (!(attrval = jas_iccattrval_clone(prof->attrtab->attrs[i].val)))622 }
623 if (!(attrval = jas_iccattrval_clone(prof->attrtab->attrs[i].val))) {
611 goto error;624 goto error;
625 }
612 return attrval;626 return attrval;
613error:627error:
614 return 0;628 return 0;
@@ -620,15 +634,17 @@ int jas_iccprof_setattr(jas_iccprof_t *prof, jas_iccattrname_t name, · 5 unmodified lines
620 int i;634 int i;
621 if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) >= 0) {635 if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) >= 0) {
622 if (val) {636 if (val) {
623 if (jas_iccattrtab_replace(prof->attrtab, i, name, val))637 if (jas_iccattrtab_replace(prof->attrtab, i, name, val)) {
624 goto error;638 goto error;
639 }
625 } else {640 } else {
626 jas_iccattrtab_delete(prof->attrtab, i);641 jas_iccattrtab_delete(prof->attrtab, i);
627 }642 }
628 } else {643 } else {
629 if (val) {644 if (val) {
630 if (jas_iccattrtab_add(prof->attrtab, -1, name, val))645 if (jas_iccattrtab_add(prof->attrtab, -1, name, val)) {
631 goto error;646 goto error;
647 }
632 } else {648 } else {
633 /* NOP */649 /* NOP */
634 }650 }
@@ -658,8 +674,10 @@ static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab) · 23 unmodified lines
658 674
659static int jas_icctagtabent_cmp(const void *src, const void *dst)675static int jas_icctagtabent_cmp(const void *src, const void *dst)
660{676{
661 const jas_icctagtabent_t *srctagtabent = JAS_CAST(const jas_icctagtabent_t *, src);677 const jas_icctagtabent_t *srctagtabent =
662 const jas_icctagtabent_t *dsttagtabent = JAS_CAST(const jas_icctagtabent_t *, dst);678 JAS_CAST(const jas_icctagtabent_t *, src);
679 const jas_icctagtabent_t *dsttagtabent =
680 JAS_CAST(const jas_icctagtabent_t *, dst);
663 if (srctagtabent->off > dsttagtabent->off) {681 if (srctagtabent->off > dsttagtabent->off) {
664 return 1;682 return 1;
665 } else if (srctagtabent->off < dsttagtabent->off) {683 } else if (srctagtabent->off < dsttagtabent->off) {
@@ -702,29 +720,29 @@ static int jas_iccgetxyz(jas_stream_t *in, jas_iccxyz_t *xyz) · 36 unmodified lines
702 return 0;720 return 0;
703}721}
704 722
705//#ifdef JAS_ENABLE_ENCODER
706
707static int jas_iccputtime(jas_stream_t *out, const jas_icctime_t *time)723static int jas_iccputtime(jas_stream_t *out, const jas_icctime_t *time)
708{724{
709 jas_iccputuint16(out, time->year);725 if (jas_iccputuint16(out, time->year) ||
710 jas_iccputuint16(out, time->month);726 jas_iccputuint16(out, time->month) ||
711 jas_iccputuint16(out, time->day);727 jas_iccputuint16(out, time->day) ||
712 jas_iccputuint16(out, time->hour);728 jas_iccputuint16(out, time->hour) ||
713 jas_iccputuint16(out, time->min);729 jas_iccputuint16(out, time->min) ||
714 jas_iccputuint16(out, time->sec);730 jas_iccputuint16(out, time->sec)) {
731 return -1;
732 }
715 return 0;733 return 0;
716}734}
717 735
718static int jas_iccputxyz(jas_stream_t *out, const jas_iccxyz_t *xyz)736static int jas_iccputxyz(jas_stream_t *out, const jas_iccxyz_t *xyz)
719{737{
720 jas_iccputuint32(out, xyz->x);738 if (jas_iccputuint32(out, xyz->x) ||
721 jas_iccputuint32(out, xyz->y);739 jas_iccputuint32(out, xyz->y) ||
722 jas_iccputuint32(out, xyz->z);740 jas_iccputuint32(out, xyz->z)) {
741 return -1;
742 }
723 return 0;743 return 0;
724}744}
725 745
726//#endif /* JAS_ENABLE_ENCODER */
727
728/******************************************************************************\746/******************************************************************************\
729* attribute table class747* attribute table class
730\******************************************************************************/748\******************************************************************************/
@@ -732,29 +750,34 @@ static int jas_iccputxyz(jas_stream_t *out, const jas_iccxyz_t *xyz) · 1 unmodified line
732static jas_iccattrtab_t *jas_iccattrtab_create()750static jas_iccattrtab_t *jas_iccattrtab_create()
733{751{
734 jas_iccattrtab_t *tab;752 jas_iccattrtab_t *tab;
735 if (!(tab = jas_malloc(sizeof(jas_iccattrtab_t))))753 if (!(tab = jas_malloc(sizeof(jas_iccattrtab_t)))) {
736 goto error;754 goto error;
755 }
737 tab->maxattrs = 0;756 tab->maxattrs = 0;
738 tab->numattrs = 0;757 tab->numattrs = 0;
739 tab->attrs = 0;758 tab->attrs = 0;
740 if (jas_iccattrtab_resize(tab, 32))759 if (jas_iccattrtab_resize(tab, 32)) {
741 goto error;760 goto error;
761 }
742 return tab;762 return tab;
743error:763error:
744 if (tab)764 if (tab) {
745 jas_iccattrtab_destroy(tab);765 jas_iccattrtab_destroy(tab);
766 }
746 return 0;767 return 0;
747}768}
748 769
749static jas_iccattrtab_t *jas_iccattrtab_copy(const jas_iccattrtab_t *attrtab)770static jas_iccattrtab_t *jas_iccattrtab_copy(const jas_iccattrtab_t *attrtab)
750{771{
751 jas_iccattrtab_t *newattrtab;772 jas_iccattrtab_t *newattrtab;
752 if (!(newattrtab = jas_iccattrtab_create()))773 if (!(newattrtab = jas_iccattrtab_create())) {
753 return NULL;774 return NULL;
775 }
754 for (unsigned i = 0; i < attrtab->numattrs; ++i) {776 for (unsigned i = 0; i < attrtab->numattrs; ++i) {
755 if (jas_iccattrtab_add(newattrtab, i, attrtab->attrs[i].name,777 if (jas_iccattrtab_add(newattrtab, i, attrtab->attrs[i].name,
756 attrtab->attrs[i].val))778 attrtab->attrs[i].val)) {
757 goto error;779 goto error;
780 }
758 }781 }
759 return newattrtab;782 return newattrtab;
760 error:783 error:
@@ -773,6 +796,29 @@ static void jas_iccattrtab_destroy(jas_iccattrtab_t *tab) · 12 unmodified lines
773 jas_free(tab);796 jas_free(tab);
774}797}
775 798
799void jas_iccattrtab_dump(const jas_iccattrtab_t *attrtab, FILE *out)
800{
801 char buf[16];
802 fprintf(out, "numattrs=%d\n", attrtab->numattrs);
803 fprintf(out, "---\n");
804 for (unsigned i = 0; i < attrtab->numattrs; ++i) {
805 const jas_iccattr_t *attr = &attrtab->attrs[i];
806 const jas_iccattrval_t *attrval = attr->val;
807 const jas_iccattrvalinfo_t *info = jas_iccattrvalinfo_lookup(attrval->type);
808 assert(info);
809 JAS_UNUSED(info);
810 fprintf(out, "attrno=%d; attrname=\"%s\"(0x%08"PRIxFAST32"); attrtype=\"%s\"(0x%08"PRIxFAST32")\n",
811 i,
812 jas_iccsigtostr(attr->name, &buf[0]),
813 attr->name,
814 jas_iccsigtostr(attrval->type, &buf[8]),
815 attrval->type
816 );
817 jas_iccattrval_dump(attrval, out);
818 fprintf(out, "---\n");
819 }
820}
821
776static int jas_iccattrtab_resize(jas_iccattrtab_t *tab, unsigned maxents)822static int jas_iccattrtab_resize(jas_iccattrtab_t *tab, unsigned maxents)
777{823{
778 jas_iccattr_t *newattrs;824 jas_iccattr_t *newattrs;
@@ -801,12 +847,14 @@ static int jas_iccattrtab_add(jas_iccattrtab_t *attrtab, int i, · 22 unmodified lines
801 return -1;847 return -1;
802 }848 }
803 }849 }
804 if (!(tmpattrval = jas_iccattrval_clone(val)))850 if (!(tmpattrval = jas_iccattrval_clone(val))) {
805 return -1;851 return -1;
852 }
806 const unsigned n = attrtab->numattrs - i;853 const unsigned n = attrtab->numattrs - i;
807 if (n > 0)854 if (n > 0) {
808 memmove(&attrtab->attrs[i + 1], &attrtab->attrs[i],855 memmove(&attrtab->attrs[i + 1], &attrtab->attrs[i],
809 n * sizeof(jas_iccattr_t));856 n * sizeof(jas_iccattr_t));
857 }
810 attr = &attrtab->attrs[i];858 attr = &attrtab->attrs[i];
811 attr->name = name;859 attr->name = name;
812 attr->val = tmpattrval;860 attr->val = tmpattrval;
@@ -819,8 +867,9 @@ static int jas_iccattrtab_replace(jas_iccattrtab_t *attrtab, unsigned i, · 6 unmodified lines
819{867{
820 jas_iccattrval_t *newval;868 jas_iccattrval_t *newval;
821 jas_iccattr_t *attr;869 jas_iccattr_t *attr;
822 if (!(newval = jas_iccattrval_clone(val)))870 if (!(newval = jas_iccattrval_clone(val))) {
823 goto error;871 goto error;
872 }
824 attr = &attrtab->attrs[i];873 attr = &attrtab->attrs[i];
825 jas_iccattrval_destroy(attr->val);874 jas_iccattrval_destroy(attr->val);
826 attr->name = name;875 attr->name = name;
@@ -834,28 +883,29 @@ static void jas_iccattrtab_delete(jas_iccattrtab_t *attrtab, unsigned i) · 7 unmodified lines
834{883{
835 unsigned n;884 unsigned n;
836 jas_iccattrval_destroy(attrtab->attrs[i].val);885 jas_iccattrval_destroy(attrtab->attrs[i].val);
837 if ((n = attrtab->numattrs - i - 1) > 0)886 if ((n = attrtab->numattrs - i - 1) > 0) {
838 memmove(&attrtab->attrs[i], &attrtab->attrs[i + 1],887 memmove(&attrtab->attrs[i], &attrtab->attrs[i + 1],
839 n * sizeof(jas_iccattr_t));888 n * sizeof(jas_iccattr_t));
889 }
840 --attrtab->numattrs;890 --attrtab->numattrs;
841}891}
842 892
843//#ifdef JAS_ENABLE_ENCODER
844static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, unsigned i,893static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, unsigned i,
845 jas_iccattrname_t *name, jas_iccattrval_t **val)894 jas_iccattrname_t *name, jas_iccattrval_t **val)
846{895{
847 jas_iccattr_t *attr;896 jas_iccattr_t *attr;
848 if (i >= attrtab->numattrs)897 if (i >= attrtab->numattrs) {
849 goto error;898 goto error;
899 }
850 attr = &attrtab->attrs[i];900 attr = &attrtab->attrs[i];
851 *name = attr->name;901 *name = attr->name;
852 if (!(*val = jas_iccattrval_clone(attr->val)))902 if (!(*val = jas_iccattrval_clone(attr->val))) {
853 goto error;903 goto error;
904 }
854 return 0;905 return 0;
855error:906error:
856 return -1;907 return -1;
857}908}
858//#endif /* JAS_ENABLE_ENCODER */
859 909
860static int jas_iccattrtab_lookup(const jas_iccattrtab_t *attrtab,910static int jas_iccattrtab_lookup(const jas_iccattrtab_t *attrtab,
861 jas_iccuint32_t name)911 jas_iccuint32_t name)
@@ -863,8 +913,9 @@ static int jas_iccattrtab_lookup(const jas_iccattrtab_t *attrtab, · 1 unmodified line
863 jas_iccattr_t *attr;913 jas_iccattr_t *attr;
864 for (unsigned i = 0; i < attrtab->numattrs; ++i) {914 for (unsigned i = 0; i < attrtab->numattrs; ++i) {
865 attr = &attrtab->attrs[i];915 attr = &attrtab->attrs[i];
866 if (attr->name == name)916 if (attr->name == name) {
867 return i;917 return i;
918 }
868 }919 }
869 return -1;920 return -1;
870}921}
@@ -878,10 +929,12 @@ jas_iccattrval_t *jas_iccattrval_create(jas_iccuint32_t type) · 7 unmodified lines
878 jas_iccattrval_t *attrval;929 jas_iccattrval_t *attrval;
879 const jas_iccattrvalinfo_t *info;930 const jas_iccattrvalinfo_t *info;
880 931
881 if (!(info = jas_iccattrvalinfo_lookup(type)))932 if (!(info = jas_iccattrvalinfo_lookup(type))) {
882 goto error;933 goto error;
883 if (!(attrval = jas_iccattrval_create0()))934 }
935 if (!(attrval = jas_iccattrval_create0())) {
884 goto error;936 goto error;
937 }
885 attrval->ops = &info->ops;938 attrval->ops = &info->ops;
886 attrval->type = type;939 attrval->type = type;
887 ++attrval->refcnt;940 ++attrval->refcnt;
@@ -903,25 +956,39 @@ void jas_iccattrval_destroy(jas_iccattrval_t *attrval) · 15 unmodified lines
903jas_eprintf("refcnt=%d\n", attrval->refcnt);956jas_eprintf("refcnt=%d\n", attrval->refcnt);
904#endif957#endif
905 if (--attrval->refcnt <= 0) {958 if (--attrval->refcnt <= 0) {
906 if (attrval->ops->destroy)959 if (attrval->ops->destroy) {
907 (*attrval->ops->destroy)(attrval);960 (*attrval->ops->destroy)(attrval);
961 }
908 jas_free(attrval);962 jas_free(attrval);
909 }963 }
910}964}
911 965
966void jas_iccattrval_dump(const jas_iccattrval_t *attrval, FILE *out)
967{
968 char buf[8];
969 jas_iccsigtostr(attrval->type, buf);
970 fprintf(out, "refcnt = %d; type = 0x%08"PRIxFAST32" %s\n", attrval->refcnt,
971 attrval->type, jas_iccsigtostr(attrval->type, &buf[0]));
972 if (attrval->ops->dump) {
973 (*attrval->ops->dump)(attrval, out);
974 }
975}
976
912int jas_iccattrval_allowmodify(jas_iccattrval_t **attrvalx)977int jas_iccattrval_allowmodify(jas_iccattrval_t **attrvalx)
913{978{
914 jas_iccattrval_t *newattrval;979 jas_iccattrval_t *newattrval;
915 jas_iccattrval_t *attrval = *attrvalx;980 jas_iccattrval_t *attrval = *attrvalx;
916 if (attrval->refcnt > 1) {981 if (attrval->refcnt > 1) {
917 if (!(newattrval = jas_iccattrval_create0()))982 if (!(newattrval = jas_iccattrval_create0())) {
918 goto error;983 goto error;
984 }
919 newattrval->ops = attrval->ops;985 newattrval->ops = attrval->ops;
920 newattrval->type = attrval->type;986 newattrval->type = attrval->type;
921 ++newattrval->refcnt;987 ++newattrval->refcnt;
922 if (newattrval->ops->copy) {988 if (newattrval->ops->copy) {
923 if ((*newattrval->ops->copy)(newattrval, attrval))989 if ((*newattrval->ops->copy)(newattrval, attrval)) {
924 goto error;990 goto error;
991 }
925 } else {992 } else {
926 memcpy(&newattrval->data, &attrval->data,993 memcpy(&newattrval->data, &attrval->data,
927 sizeof(newattrval->data));994 sizeof(newattrval->data));
@@ -939,8 +1006,9 @@ error: · 11 unmodified lines
939static jas_iccattrval_t *jas_iccattrval_create0()1006static jas_iccattrval_t *jas_iccattrval_create0()
940{1007{
941 jas_iccattrval_t *attrval;1008 jas_iccattrval_t *attrval;
942 if (!(attrval = jas_malloc(sizeof(jas_iccattrval_t))))1009 if (!(attrval = jas_malloc(sizeof(jas_iccattrval_t)))) {
943 return 0;1010 return 0;
1011 }
944 memset(attrval, 0, sizeof(jas_iccattrval_t));1012 memset(attrval, 0, sizeof(jas_iccattrval_t));
945 attrval->refcnt = 0;1013 attrval->refcnt = 0;
946 attrval->ops = 0;1014 attrval->ops = 0;
@@ -955,31 +1023,36 @@ static jas_iccattrval_t *jas_iccattrval_create0() · 8 unmodified lines
955static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in,1023static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in,
956 unsigned len)1024 unsigned len)
957{1025{
958 assert(len == 4 * 3);1026 if (len != 4 * 3) {
959 (void)len;1027 return -1;
1028 }
960 return jas_iccgetxyz(in, &attrval->data.xyz);1029 return jas_iccgetxyz(in, &attrval->data.xyz);
961}1030}
962 1031
963//#ifdef JAS_ENABLE_ENCODER
964static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out)1032static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out)
965{1033{
966 const jas_iccxyz_t *xyz = &attrval->data.xyz;1034 const jas_iccxyz_t *xyz = &attrval->data.xyz;
967 if (jas_iccputuint32(out, xyz->x) ||1035 if (jas_iccputuint32(out, xyz->x) ||
968 jas_iccputuint32(out, xyz->y) ||1036 jas_iccputuint32(out, xyz->y) ||
969 jas_iccputuint32(out, xyz->z))1037 jas_iccputuint32(out, xyz->z)) {
970 return -1;1038 return -1;
1039 }
971 return 0;1040 return 0;
972}1041}
973//#endif /* JAS_ENABLE_ENCODER */
974 1042
975static unsigned jas_iccxyz_getsize(const jas_iccattrval_t *attrval)1043static unsigned jas_iccxyz_getsize(const jas_iccattrval_t *attrval)
976{1044{
977 /* Avoid compiler warnings about unused parameters. */1045 JAS_UNUSED(attrval);
978 USED(attrval);
979
980 return 12;1046 return 12;
981}1047}
982 1048
1049static void jas_iccxyz_dump(const jas_iccattrval_t *attrval, FILE *out)
1050{
1051 const jas_iccxyz_t *xyz = &attrval->data.xyz;
1052 fprintf(out, "(%f, %f, %f)\n", xyz->x / 65536.0, xyz->y / 65536.0,
1053 xyz->z / 65536.0);
1054}
1055
983/******************************************************************************\1056/******************************************************************************\
984* attribute table class1057* attribute table class
985\******************************************************************************/1058\******************************************************************************/
@@ -996,9 +1069,8 @@ static void jas_icccurv_destroy(jas_iccattrval_t *attrval) · 10 unmodified lines
996static int jas_icccurv_copy(jas_iccattrval_t *attrval,1069static int jas_icccurv_copy(jas_iccattrval_t *attrval,
997 const jas_iccattrval_t *othattrval)1070 const jas_iccattrval_t *othattrval)
998{1071{
999 /* Avoid compiler warnings about unused parameters. */1072 JAS_UNUSED(attrval);
1000 USED(attrval);1073 JAS_UNUSED(othattrval);
1001 USED(othattrval);
1002 1074
1003 /* Not yet implemented. */1075 /* Not yet implemented. */
1004 abort();1076 abort();
@@ -1013,17 +1085,21 @@ static int jas_icccurv_input(jas_iccattrval_t *attrval, jas_stream_t *in, · 8 unmodified lines
1013 curv->numents = 0;1085 curv->numents = 0;
1014 curv->ents = 0;1086 curv->ents = 0;
1015 1087
1016 if (jas_iccgetuint32(in, &curv->numents))1088 if (jas_iccgetuint32(in, &curv->numents)) {
1017 goto error;1089 goto error;
1018 if (!(curv->ents = jas_alloc2(curv->numents, sizeof(jas_iccuint16_t))))1090 }
1091 if (!(curv->ents = jas_alloc2(curv->numents, sizeof(jas_iccuint16_t)))) {
1019 goto error;1092 goto error;
1093 }
1020 for (unsigned i = 0; i < curv->numents; ++i) {1094 for (unsigned i = 0; i < curv->numents; ++i) {
1021 if (jas_iccgetuint16(in, &curv->ents[i]))1095 if (jas_iccgetuint16(in, &curv->ents[i])) {
1022 goto error;1096 goto error;
1097 }
1023 }1098 }
1024 1099
1025 if (4 + 2 * curv->numents != cnt)1100 if (4 + 2 * curv->numents != cnt) {
1026 goto error;1101 goto error;
1102 }
1027 return 0;1103 return 0;
1028 1104
1029error:1105error:
@@ -1037,22 +1113,37 @@ static unsigned jas_icccurv_getsize(const jas_iccattrval_t *attrval) · 7 unmodified lines
1037 return 4 + 2 * curv->numents;1113 return 4 + 2 * curv->numents;
1038}1114}
1039 1115
1040//#ifdef JAS_ENABLE_ENCODER
1041static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out)1116static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1042{1117{
1043 const jas_icccurv_t *curv = &attrval->data.curv;1118 const jas_icccurv_t *curv = &attrval->data.curv;
1044 1119
1045 if (jas_iccputuint32(out, curv->numents))1120 if (jas_iccputuint32(out, curv->numents)) {
1046 goto error;1121 goto error;
1122 }
1047 for (unsigned i = 0; i < curv->numents; ++i) {1123 for (unsigned i = 0; i < curv->numents; ++i) {
1048 if (jas_iccputuint16(out, curv->ents[i]))1124 if (jas_iccputuint16(out, curv->ents[i])) {
1049 goto error;1125 goto error;
1126 }
1050 }1127 }
1051 return 0;1128 return 0;
1052error:1129error:
1053 return -1;1130 return -1;
1054}1131}
1055//#endif /* JAS_ENABLE_ENCODER */1132
1133static void jas_icccurv_dump(const jas_iccattrval_t *attrval, FILE *out)
1134{
1135 const jas_icccurv_t *curv = &attrval->data.curv;
1136 fprintf(out, "number of entries = %"PRIuFAST32"\n", curv->numents);
1137 if (curv->numents == 1) {
1138 fprintf(out, "gamma = %f\n", curv->ents[0] / 256.0);
1139 } else {
1140 for (unsigned i = 0; i < curv->numents; ++i) {
1141 if (i < 3 || i >= curv->numents - 3) {
1142 fprintf(out, "entry[%d] = %f\n", i, curv->ents[i] / 65535.0);
1143 }
1144 }
1145 }
1146}
1056 1147
1057/******************************************************************************\1148/******************************************************************************\
1058*1149*
@@ -1076,10 +1167,9 @@ static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval, · 17 unmodified lines
1076{1167{
1077 jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;1168 jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1078 1169
1079 /* Avoid compiler warnings about unused parameters. */1170 JAS_UNUSED(attrval);
1080 USED(attrval);1171 JAS_UNUSED(othattrval);
1081 USED(othattrval);1172 JAS_UNUSED(txtdesc);
1082 USED(txtdesc);
1083 1173
1084 /* Not yet implemented. */1174 /* Not yet implemented. */
1085 abort();1175 abort();
@@ -1093,31 +1183,41 @@ static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in, · 7 unmodified lines
1093 jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;1183 jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1094 txtdesc->ascdata = 0;1184 txtdesc->ascdata = 0;
1095 txtdesc->ucdata = 0;1185 txtdesc->ucdata = 0;
1096 if (jas_iccgetuint32(in, &txtdesc->asclen))1186 if (jas_iccgetuint32(in, &txtdesc->asclen)) {
1097 goto error;1187 goto error;
1098 if (txtdesc->asclen < 1)1188 }
1189 if (txtdesc->asclen < 1) {
1099 goto error;1190 goto error;
1100 if (!(txtdesc->ascdata = jas_malloc(txtdesc->asclen)))1191 }
1192 if (!(txtdesc->ascdata = jas_malloc(txtdesc->asclen))) {
1101 goto error;1193 goto error;
1194 }
1102 if (jas_stream_read(in, txtdesc->ascdata, txtdesc->asclen) !=1195 if (jas_stream_read(in, txtdesc->ascdata, txtdesc->asclen) !=
1103 txtdesc->asclen)1196 txtdesc->asclen) {
1104 goto error;1197 goto error;
1198 }
1105 txtdesc->ascdata[txtdesc->asclen - 1] = '\0';1199 txtdesc->ascdata[txtdesc->asclen - 1] = '\0';
1106 if (jas_iccgetuint32(in, &txtdesc->uclangcode) ||1200 if (jas_iccgetuint32(in, &txtdesc->uclangcode) ||
1107 jas_iccgetuint32(in, &txtdesc->uclen))1201 jas_iccgetuint32(in, &txtdesc->uclen)) {
1108 goto error;1202 goto error;
1109 if (!(txtdesc->ucdata = jas_alloc2(txtdesc->uclen, 2)))1203 }
1204 if (!(txtdesc->ucdata = jas_alloc2(txtdesc->uclen, 2))) {
1110 goto error;1205 goto error;
1206 }
1111 if (jas_stream_read(in, txtdesc->ucdata, txtdesc->uclen * 2) !=1207 if (jas_stream_read(in, txtdesc->ucdata, txtdesc->uclen * 2) !=
1112 txtdesc->uclen * 2)1208 txtdesc->uclen * 2) {
1113 goto error;1209 goto error;
1114 if (jas_iccgetuint16(in, &txtdesc->sccode))1210 }
1211 if (jas_iccgetuint16(in, &txtdesc->sccode)) {
1115 goto error;1212 goto error;
1116 if ((c = jas_stream_getc(in)) == EOF)1213 }
1214 if ((c = jas_stream_getc(in)) == EOF) {
1117 goto error;1215 goto error;
1216 }
1118 txtdesc->maclen = c;1217 txtdesc->maclen = c;
1119 if (jas_stream_read(in, txtdesc->macdata, 67) != 67)1218 if (jas_stream_read(in, txtdesc->macdata, 67) != 67) {
1120 goto error;1219 goto error;
1220 }
1121 txtdesc->asclen = JAS_CAST(jas_iccuint32_t, strlen(txtdesc->ascdata) + 1);1221 txtdesc->asclen = JAS_CAST(jas_iccuint32_t, strlen(txtdesc->ascdata) + 1);
1122#define WORKAROUND_BAD_PROFILES1222#define WORKAROUND_BAD_PROFILES
1123#ifdef WORKAROUND_BAD_PROFILES1223#ifdef WORKAROUND_BAD_PROFILES
@@ -1126,12 +1226,14 @@ static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in, · 2 unmodified lines
1126 return -1;1226 return -1;
1127 }1227 }
1128 if (n < cnt) {1228 if (n < cnt) {
1129 if (jas_stream_gobble(in, cnt - n) != (int)(cnt - n))1229 if (jas_stream_gobble(in, cnt - n) != (int)(cnt - n)) {
1130 goto error;1230 goto error;
1231 }
1131 }1232 }
1132#else1233#else
1133 if (txtdesc->asclen + txtdesc->uclen * 2 + 15 + 67 != cnt)1234 if (txtdesc->asclen + txtdesc->uclen * 2 + 15 + 67 != cnt) {
1134 return -1;1235 return -1;
1236 }
1135#endif1237#endif
1136 return 0;1238 return 0;
1137error:1239error:
@@ -1145,7 +1247,6 @@ static unsigned jas_icctxtdesc_getsize(const jas_iccattrval_t *attrval) · 7 unmodified lines
1145 return strlen(txtdesc->ascdata) + 1 + txtdesc->uclen * 2 + 15 + 67;1247 return strlen(txtdesc->ascdata) + 1 + txtdesc->uclen * 2 + 15 + 67;
1146}1248}
1147 1249
1148//#ifdef JAS_ENABLE_ENCODER
1149static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out)1250static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1150{1251{
1151 const jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;1252 const jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
@@ -1154,22 +1255,35 @@ static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out) · 2 unmodified lines
1154 jas_stream_putc(out, 0) == EOF ||1255 jas_stream_putc(out, 0) == EOF ||
1155 jas_iccputuint32(out, txtdesc->uclangcode) ||1256 jas_iccputuint32(out, txtdesc->uclangcode) ||
1156 jas_iccputuint32(out, txtdesc->uclen) ||1257 jas_iccputuint32(out, txtdesc->uclen) ||
1157 jas_stream_write(out, txtdesc->ucdata, txtdesc->uclen * 2) != txtdesc->uclen * 2 ||1258 jas_stream_write(out, txtdesc->ucdata, txtdesc->uclen * 2) !=
1259 txtdesc->uclen * 2 ||
1158 jas_iccputuint16(out, txtdesc->sccode) ||1260 jas_iccputuint16(out, txtdesc->sccode) ||
1159 jas_stream_putc(out, txtdesc->maclen) == EOF)1261 jas_stream_putc(out, txtdesc->maclen) == EOF) {
1160 goto error;1262 goto error;
1263 }
1161 if (txtdesc->maclen > 0) {1264 if (txtdesc->maclen > 0) {
1162 if (jas_stream_write(out, txtdesc->macdata, 67) != 67)1265 if (jas_stream_write(out, txtdesc->macdata, 67) != 67) {
1163 goto error;1266 goto error;
1267 }
1164 } else {1268 } else {
1165 if (jas_stream_pad(out, 67, 0) != 67)1269 if (jas_stream_pad(out, 67, 0) != 67) {
1166 goto error;1270 goto error;
1271 }
1167 }1272 }
1168 return 0;1273 return 0;
1169error:1274error:
1170 return -1;1275 return -1;
1171}1276}
1172//#endif /* JAS_ENABLE_ENCODER */1277
1278static void jas_icctxtdesc_dump(const jas_iccattrval_t *attrval, FILE *out)
1279{
1280 const jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
1281 fprintf(out, "ascii = \"%s\"\n", txtdesc->ascdata);
1282 fprintf(out, "uclangcode = %"PRIuFAST32"; uclen = %"PRIuFAST32"\n",
1283 txtdesc->uclangcode, txtdesc->uclen);
1284 fprintf(out, "sccode = %"PRIuFAST16"\n", txtdesc->sccode);
1285 fprintf(out, "maclen = %d\n", txtdesc->maclen);
1286}
1173 1287
1174/******************************************************************************\1288/******************************************************************************\
1175*1289*
@@ -1189,8 +1303,9 @@ static int jas_icctxt_copy(jas_iccattrval_t *attrval, · 13 unmodified lines
1189{1303{
1190 jas_icctxt_t *txt = &attrval->data.txt;1304 jas_icctxt_t *txt = &attrval->data.txt;
1191 const jas_icctxt_t *othtxt = &othattrval->data.txt;1305 const jas_icctxt_t *othtxt = &othattrval->data.txt;
1192 if (!(txt->string = strdup(othtxt->string)))1306 if (!(txt->string = jas_strdup(othtxt->string))) {
1193 return -1;1307 return -1;
1308 }
1194 return 0;1309 return 0;
1195}1310}
1196 1311
@@ -1199,13 +1314,16 @@ static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in, · 2 unmodified lines
1199{1314{
1200 jas_icctxt_t *txt = &attrval->data.txt;1315 jas_icctxt_t *txt = &attrval->data.txt;
1201 txt->string = 0;1316 txt->string = 0;
1202 if (!(txt->string = jas_malloc(cnt)))1317 if (!(txt->string = jas_malloc(cnt))) {
1203 goto error;1318 goto error;
1204 if (jas_stream_read(in, txt->string, cnt) != cnt)1319 }
1320 if (jas_stream_read(in, txt->string, cnt) != cnt) {
1205 goto error;1321 goto error;
1322 }
1206 txt->string[cnt - 1] = '\0';1323 txt->string[cnt - 1] = '\0';
1207 if (strlen(txt->string) + 1 != cnt)1324 if (strlen(txt->string) + 1 != cnt) {
1208 goto error;1325 goto error;
1326 }
1209 return 0;1327 return 0;
1210error:1328error:
1211 jas_icctxt_destroy(attrval);1329 jas_icctxt_destroy(attrval);
@@ -1218,16 +1336,21 @@ static unsigned jas_icctxt_getsize(const jas_iccattrval_t *attrval) · 6 unmodified lines
1218 return strlen(txt->string) + 1;1336 return strlen(txt->string) + 1;
1219}1337}
1220 1338
1221//#ifdef JAS_ENABLE_ENCODER
1222static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out)1339static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1223{1340{
1224 const jas_icctxt_t *txt = &attrval->data.txt;1341 const jas_icctxt_t *txt = &attrval->data.txt;
1225 if (jas_stream_puts(out, txt->string) ||1342 if (jas_stream_puts(out, txt->string) ||
1226 jas_stream_putc(out, 0) == EOF)1343 jas_stream_putc(out, 0) == EOF) {
1227 return -1;1344 return -1;
1345 }
1228 return 0;1346 return 0;
1229}1347}
1230//#endif /* JAS_ENABLE_ENCODER */1348
1349static void jas_icctxt_dump(const jas_iccattrval_t *attrval, FILE *out)
1350{
1351 const jas_icctxt_t *txt = &attrval->data.txt;
1352 fprintf(out, "string = \"%s\"\n", txt->string);
1353}
1231 1354
1232/******************************************************************************\1355/******************************************************************************\
1233*1356*
@@ -1261,9 +1384,8 @@ static void jas_icclut8_destroy(jas_iccattrval_t *attrval) · 27 unmodified lines
1261static int jas_icclut8_copy(jas_iccattrval_t *attrval,1384static int jas_icclut8_copy(jas_iccattrval_t *attrval,
1262 const jas_iccattrval_t *othattrval)1385 const jas_iccattrval_t *othattrval)
1263{1386{
1264 /* Avoid compiler warnings about unused parameters. */1387 JAS_UNUSED(attrval);
1265 USED(attrval);1388 JAS_UNUSED(othattrval);
1266 USED(othattrval);
1267 abort();1389 abort();
1268 return -1;1390 return -1;
1269}1391}
@@ -1280,54 +1402,64 @@ static int jas_icclut8_input(jas_iccattrval_t *attrval, jas_stream_t *in, · 10 unmodified lines
1280 if (jas_iccgetuint8(in, &lut8->numinchans) ||1402 if (jas_iccgetuint8(in, &lut8->numinchans) ||
1281 jas_iccgetuint8(in, &lut8->numoutchans) ||1403 jas_iccgetuint8(in, &lut8->numoutchans) ||
1282 jas_iccgetuint8(in, &lut8->clutlen) ||1404 jas_iccgetuint8(in, &lut8->clutlen) ||
1283 jas_stream_getc(in) == EOF)1405 jas_stream_getc(in) == EOF) {
1284 goto error;1406 goto error;
1407 }
1285 for (unsigned i = 0; i < 3; ++i) {1408 for (unsigned i = 0; i < 3; ++i) {
1286 for (unsigned j = 0; j < 3; ++j) {1409 for (unsigned j = 0; j < 3; ++j) {
1287 if (jas_iccgetsint32(in, &lut8->e[i][j]))1410 if (jas_iccgetsint32(in, &lut8->e[i][j])) {
1288 goto error;1411 goto error;
1412 }
1289 }1413 }
1290 }1414 }
1291 if (jas_iccgetuint16(in, &lut8->numintabents) ||1415 if (jas_iccgetuint16(in, &lut8->numintabents) ||
1292 jas_iccgetuint16(in, &lut8->numouttabents))1416 jas_iccgetuint16(in, &lut8->numouttabents)) {
1293 goto error;1417 goto error;
1418 }
1294 const unsigned clutsize = jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans;1419 const unsigned clutsize = jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans;
1295 if (!(lut8->clut = jas_alloc2(clutsize, sizeof(jas_iccuint8_t))) ||1420 if (!(lut8->clut = jas_alloc2(clutsize, sizeof(jas_iccuint8_t))) ||
1296 !(lut8->intabsbuf = jas_alloc3(lut8->numinchans,1421 !(lut8->intabsbuf = jas_alloc3(lut8->numinchans,
1297 lut8->numintabents, sizeof(jas_iccuint8_t))) ||1422 lut8->numintabents, sizeof(jas_iccuint8_t))) ||
1298 !(lut8->intabs = jas_alloc2(lut8->numinchans,1423 !(lut8->intabs = jas_alloc2(lut8->numinchans,
1299 sizeof(jas_iccuint8_t *))))1424 sizeof(jas_iccuint8_t *)))) {
1300 goto error;1425 goto error;
1426 }
1301 for (unsigned i = 0; i < lut8->numinchans; ++i)1427 for (unsigned i = 0; i < lut8->numinchans; ++i)
1302 lut8->intabs[i] = &lut8->intabsbuf[i * lut8->numintabents];1428 lut8->intabs[i] = &lut8->intabsbuf[i * lut8->numintabents];
1303 if (!(lut8->outtabsbuf = jas_alloc3(lut8->numoutchans,1429 if (!(lut8->outtabsbuf = jas_alloc3(lut8->numoutchans,
1304 lut8->numouttabents, sizeof(jas_iccuint8_t))) ||1430 lut8->numouttabents, sizeof(jas_iccuint8_t))) ||
1305 !(lut8->outtabs = jas_alloc2(lut8->numoutchans,1431 !(lut8->outtabs = jas_alloc2(lut8->numoutchans,
1306 sizeof(jas_iccuint8_t *))))1432 sizeof(jas_iccuint8_t *)))) {
1307 goto error;1433 goto error;
1308 for (unsigned i = 0; i < lut8->numoutchans; ++i)1434 }
1435 for (unsigned i = 0; i < lut8->numoutchans; ++i) {
1309 lut8->outtabs[i] = &lut8->outtabsbuf[i * lut8->numouttabents];1436 lut8->outtabs[i] = &lut8->outtabsbuf[i * lut8->numouttabents];
1437 }
1310 for (unsigned i = 0; i < lut8->numinchans; ++i) {1438 for (unsigned i = 0; i < lut8->numinchans; ++i) {
1311 for (unsigned j = 0; j < lut8->numintabents; ++j) {1439 for (unsigned j = 0; j < lut8->numintabents; ++j) {
1312 if (jas_iccgetuint8(in, &lut8->intabs[i][j]))1440 if (jas_iccgetuint8(in, &lut8->intabs[i][j])) {
1313 goto error;1441 goto error;
1442 }
1314 }1443 }
1315 }1444 }
1316 for (unsigned i = 0; i < lut8->numoutchans; ++i) {1445 for (unsigned i = 0; i < lut8->numoutchans; ++i) {
1317 for (unsigned j = 0; j < lut8->numouttabents; ++j) {1446 for (unsigned j = 0; j < lut8->numouttabents; ++j) {
1318 if (jas_iccgetuint8(in, &lut8->outtabs[i][j]))1447 if (jas_iccgetuint8(in, &lut8->outtabs[i][j])) {
1319 goto error;1448 goto error;
1449 }
1320 }1450 }
1321 }1451 }
1322 for (unsigned i = 0; i < clutsize; ++i) {1452 for (unsigned i = 0; i < clutsize; ++i) {
1323 if (jas_iccgetuint8(in, &lut8->clut[i]))1453 if (jas_iccgetuint8(in, &lut8->clut[i])) {
1324 goto error;1454 goto error;
1455 }
1325 }1456 }
1326 if (44 + lut8->numinchans * lut8->numintabents +1457 if (44 + lut8->numinchans * lut8->numintabents +
1327 lut8->numoutchans * lut8->numouttabents +1458 lut8->numoutchans * lut8->numouttabents +
1328 jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans !=1459 jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans !=
1329 cnt)1460 cnt) {
1330 goto error;1461 goto error;
1462 }
1331 return 0;1463 return 0;
1332error:1464error:
1333 jas_icclut8_destroy(attrval);1465 jas_icclut8_destroy(attrval);
@@ -1342,7 +1474,6 @@ static unsigned jas_icclut8_getsize(const jas_iccattrval_t *attrval) · 8 unmodified lines
1342 jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans;1474 jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans;
1343}1475}
1344 1476
1345//#ifdef JAS_ENABLE_ENCODER
1346static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out)1477static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1347{1478{
1348 jas_icclut8_t *lut8 = &attrval->data.lut8;1479 jas_icclut8_t *lut8 = &attrval->data.lut8;
@@ -1354,34 +1485,57 @@ static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out) · 5 unmodified lines
1354 if (jas_stream_putc(out, lut8->numinchans) == EOF ||1485 if (jas_stream_putc(out, lut8->numinchans) == EOF ||
1355 jas_stream_putc(out, lut8->numoutchans) == EOF ||1486 jas_stream_putc(out, lut8->numoutchans) == EOF ||
1356 jas_stream_putc(out, lut8->clutlen) == EOF ||1487 jas_stream_putc(out, lut8->clutlen) == EOF ||
1357 jas_stream_putc(out, 0) == EOF)1488 jas_stream_putc(out, 0) == EOF) {
1358 goto error;1489 goto error;
1490 }
1359 for (unsigned i = 0; i < 3; ++i) {1491 for (unsigned i = 0; i < 3; ++i) {
1360 for (unsigned j = 0; j < 3; ++j) {1492 for (unsigned j = 0; j < 3; ++j) {
1361 if (jas_iccputsint32(out, lut8->e[i][j]))1493 if (jas_iccputsint32(out, lut8->e[i][j])) {
1362 goto error;1494 goto error;
1495 }
1363 }1496 }
1364 }1497 }
1365 if (jas_iccputuint16(out, lut8->numintabents) ||1498 if (jas_iccputuint16(out, lut8->numintabents) ||
1366 jas_iccputuint16(out, lut8->numouttabents))1499 jas_iccputuint16(out, lut8->numouttabents)) {
1367 goto error;1500 goto error;
1368 for (unsigned i = 0, n = lut8->numinchans * lut8->numintabents; i < n; ++i) {1501 }
1369 if (jas_iccputuint8(out, lut8->intabsbuf[i]))1502 for (unsigned i = 0, n = lut8->numinchans * lut8->numintabents; i < n;
1503 ++i) {
1504 if (jas_iccputuint8(out, lut8->intabsbuf[i])) {
1370 goto error;1505 goto error;
1506 }
1371 }1507 }
1372 for (unsigned i = 0, n = lut8->numoutchans * lut8->numouttabents; i < n; ++i) {1508 for (unsigned i = 0, n = lut8->numoutchans * lut8->numouttabents; i < n;
1373 if (jas_iccputuint8(out, lut8->outtabsbuf[i]))1509 ++i) {
1510 if (jas_iccputuint8(out, lut8->outtabsbuf[i])) {
1374 goto error;1511 goto error;
1512 }
1375 }1513 }
1376 for (unsigned i = 0, n = jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans; i < n; ++i) {1514 for (unsigned i = 0, n = jas_iccpowi(lut8->clutlen, lut8->numinchans) *
1377 if (jas_iccputuint8(out, lut8->clut[i]))1515 lut8->numoutchans; i < n; ++i) {
1516 if (jas_iccputuint8(out, lut8->clut[i])) {
1378 goto error;1517 goto error;
1518 }
1379 }1519 }
1380 return 0;1520 return 0;
1381error:1521error:
1382 return -1;1522 return -1;
1383}1523}
1384//#endif /* JAS_ENABLE_ENCODER */1524
1525static void jas_icclut8_dump(const jas_iccattrval_t *attrval, FILE *out)
1526{
1527 const jas_icclut8_t *lut8 = &attrval->data.lut8;
1528 fprintf(out, "numinchans=%d, numoutchans=%d, clutlen=%d\n",
1529 lut8->numinchans, lut8->numoutchans, lut8->clutlen);
1530 for (unsigned i = 0; i < 3; ++i) {
1531 for (unsigned j = 0; j < 3; ++j) {
1532 fprintf(out, "e[%d][%d]=%f ", i, j, lut8->e[i][j] / 65536.0);
1533 }
1534 fprintf(out, "\n");
1535 }
1536 fprintf(out, "numintabents=%"PRIuFAST16", numouttabents=%"PRIuFAST16"\n",
1537 lut8->numintabents, lut8->numouttabents);
1538}
1385 1539
1386/******************************************************************************\1540/******************************************************************************\
1387*1541*
@@ -1415,9 +1569,9 @@ static void jas_icclut16_destroy(jas_iccattrval_t *attrval) · 27 unmodified lines
1415static int jas_icclut16_copy(jas_iccattrval_t *attrval,1569static int jas_icclut16_copy(jas_iccattrval_t *attrval,
1416 const jas_iccattrval_t *othattrval)1570 const jas_iccattrval_t *othattrval)
1417{1571{
1418 /* Avoid compiler warnings about unused parameters. */1572 JAS_UNUSED(attrval);
1419 USED(attrval);1573 JAS_UNUSED(othattrval);
1420 USED(othattrval);1574
1421 /* Not yet implemented. */1575 /* Not yet implemented. */
1422 abort();1576 abort();
1423 return -1;1577 return -1;
@@ -1435,54 +1589,66 @@ static int jas_icclut16_input(jas_iccattrval_t *attrval, jas_stream_t *in, · 11 unmodified lines
1435 if (jas_iccgetuint8(in, &lut16->numinchans) ||1589 if (jas_iccgetuint8(in, &lut16->numinchans) ||
1436 jas_iccgetuint8(in, &lut16->numoutchans) ||1590 jas_iccgetuint8(in, &lut16->numoutchans) ||
1437 jas_iccgetuint8(in, &lut16->clutlen) ||1591 jas_iccgetuint8(in, &lut16->clutlen) ||
1438 jas_stream_getc(in) == EOF)1592 jas_stream_getc(in) == EOF) {
1439 goto error;1593 goto error;
1594 }
1440 for (unsigned i = 0; i < 3; ++i) {1595 for (unsigned i = 0; i < 3; ++i) {
1441 for (unsigned j = 0; j < 3; ++j) {1596 for (unsigned j = 0; j < 3; ++j) {
1442 if (jas_iccgetsint32(in, &lut16->e[i][j]))1597 if (jas_iccgetsint32(in, &lut16->e[i][j])) {
1443 goto error;1598 goto error;
1599 }
1444 }1600 }
1445 }1601 }
1446 if (jas_iccgetuint16(in, &lut16->numintabents) ||1602 if (jas_iccgetuint16(in, &lut16->numintabents) ||
1447 jas_iccgetuint16(in, &lut16->numouttabents))1603 jas_iccgetuint16(in, &lut16->numouttabents)) {
1448 goto error;1604 goto error;
1449 const unsigned clutsize = jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans;1605 }
1606 const unsigned clutsize = jas_iccpowi(lut16->clutlen, lut16->numinchans) *
1607 lut16->numoutchans;
1450 if (!(lut16->clut = jas_alloc2(clutsize, sizeof(jas_iccuint16_t))) ||1608 if (!(lut16->clut = jas_alloc2(clutsize, sizeof(jas_iccuint16_t))) ||
1451 !(lut16->intabsbuf = jas_alloc3(lut16->numinchans,1609 !(lut16->intabsbuf = jas_alloc3(lut16->numinchans,
1452 lut16->numintabents, sizeof(jas_iccuint16_t))) ||1610 lut16->numintabents, sizeof(jas_iccuint16_t))) ||
1453 !(lut16->intabs = jas_alloc2(lut16->numinchans,1611 !(lut16->intabs = jas_alloc2(lut16->numinchans,
1454 sizeof(jas_iccuint16_t *))))1612 sizeof(jas_iccuint16_t *)))) {
1455 goto error;1613 goto error;
1456 for (unsigned i = 0; i < lut16->numinchans; ++i)1614 }
1615 for (unsigned i = 0; i < lut16->numinchans; ++i) {
1457 lut16->intabs[i] = &lut16->intabsbuf[i * lut16->numintabents];1616 lut16->intabs[i] = &lut16->intabsbuf[i * lut16->numintabents];
1617 }
1458 if (!(lut16->outtabsbuf = jas_alloc3(lut16->numoutchans,1618 if (!(lut16->outtabsbuf = jas_alloc3(lut16->numoutchans,
1459 lut16->numouttabents, sizeof(jas_iccuint16_t))) ||1619 lut16->numouttabents, sizeof(jas_iccuint16_t))) ||
1460 !(lut16->outtabs = jas_alloc2(lut16->numoutchans,1620 !(lut16->outtabs = jas_alloc2(lut16->numoutchans,
1461 sizeof(jas_iccuint16_t *))))1621 sizeof(jas_iccuint16_t *)))) {
1462 goto error;1622 goto error;
1463 for (unsigned i = 0; i < lut16->numoutchans; ++i)1623 }
1624 for (unsigned i = 0; i < lut16->numoutchans; ++i) {
1464 lut16->outtabs[i] = &lut16->outtabsbuf[i * lut16->numouttabents];1625 lut16->outtabs[i] = &lut16->outtabsbuf[i * lut16->numouttabents];
1626 }
1465 for (unsigned i = 0; i < lut16->numinchans; ++i) {1627 for (unsigned i = 0; i < lut16->numinchans; ++i) {
1466 for (unsigned j = 0; j < lut16->numintabents; ++j) {1628 for (unsigned j = 0; j < lut16->numintabents; ++j) {
1467 if (jas_iccgetuint16(in, &lut16->intabs[i][j]))1629 if (jas_iccgetuint16(in, &lut16->intabs[i][j])) {
1468 goto error;1630 goto error;
1631 }
1469 }1632 }
1470 }1633 }
1471 for (unsigned i = 0; i < lut16->numoutchans; ++i) {1634 for (unsigned i = 0; i < lut16->numoutchans; ++i) {
1472 for (unsigned j = 0; j < lut16->numouttabents; ++j) {1635 for (unsigned j = 0; j < lut16->numouttabents; ++j) {
1473 if (jas_iccgetuint16(in, &lut16->outtabs[i][j]))1636 if (jas_iccgetuint16(in, &lut16->outtabs[i][j])) {
1474 goto error;1637 goto error;
1638 }
1475 }1639 }
1476 }1640 }
1477 for (unsigned i = 0; i < clutsize; ++i) {1641 for (unsigned i = 0; i < clutsize; ++i) {
1478 if (jas_iccgetuint16(in, &lut16->clut[i]))1642 if (jas_iccgetuint16(in, &lut16->clut[i])) {
1479 goto error;1643 goto error;
1644 }
1480 }1645 }
1481 if (44 + 2 * (lut16->numinchans * lut16->numintabents +1646 if (44 + 2 * (lut16->numinchans * lut16->numintabents +
1482 lut16->numoutchans * lut16->numouttabents +1647 lut16->numoutchans * lut16->numouttabents +
1483 jas_iccpowi(lut16->clutlen, lut16->numinchans) *1648 jas_iccpowi(lut16->clutlen, lut16->numinchans) *
1484 lut16->numoutchans) != cnt)1649 lut16->numoutchans) != cnt) {
1485 goto error;1650 goto error;
1651 }
1486 return 0;1652 return 0;
1487error:1653error:
1488 jas_icclut16_destroy(attrval);1654 jas_icclut16_destroy(attrval);
@@ -1497,41 +1663,63 @@ static unsigned jas_icclut16_getsize(const jas_iccattrval_t *attrval) · 8 unmodified lines
1497 jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans);1663 jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans);
1498}1664}
1499 1665
1500//#ifdef JAS_ENABLE_ENCODER
1501static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out)1666static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out)
1502{1667{
1503 const jas_icclut16_t *lut16 = &attrval->data.lut16;1668 const jas_icclut16_t *lut16 = &attrval->data.lut16;
1504 if (jas_stream_putc(out, lut16->numinchans) == EOF ||1669 if (jas_stream_putc(out, lut16->numinchans) == EOF ||
1505 jas_stream_putc(out, lut16->numoutchans) == EOF ||1670 jas_stream_putc(out, lut16->numoutchans) == EOF ||
1506 jas_stream_putc(out, lut16->clutlen) == EOF ||1671 jas_stream_putc(out, lut16->clutlen) == EOF ||
1507 jas_stream_putc(out, 0) == EOF)1672 jas_stream_putc(out, 0) == EOF) {
1508 goto error;1673 goto error;
1674 }
1509 for (unsigned i = 0; i < 3; ++i) {1675 for (unsigned i = 0; i < 3; ++i) {
1510 for (unsigned j = 0; j < 3; ++j) {1676 for (unsigned j = 0; j < 3; ++j) {
1511 if (jas_iccputsint32(out, lut16->e[i][j]))1677 if (jas_iccputsint32(out, lut16->e[i][j])) {
1512 goto error;1678 goto error;
1679 }
1513 }1680 }
1514 }1681 }
1515 if (jas_iccputuint16(out, lut16->numintabents) ||1682 if (jas_iccputuint16(out, lut16->numintabents) ||
1516 jas_iccputuint16(out, lut16->numouttabents))1683 jas_iccputuint16(out, lut16->numouttabents)) {
1517 goto error;1684 goto error;
1518 for (unsigned i = 0, n = lut16->numinchans * lut16->numintabents; i < n; ++i) {1685 }
1519 if (jas_iccputuint16(out, lut16->intabsbuf[i]))1686 for (unsigned i = 0, n = lut16->numinchans * lut16->numintabents; i < n;
1687 ++i) {
1688 if (jas_iccputuint16(out, lut16->intabsbuf[i])) {
1520 goto error;1689 goto error;
1690 }
1521 }1691 }
1522 for (unsigned i = 0, n = lut16->numoutchans * lut16->numouttabents; i < n; ++i) {1692 for (unsigned i = 0, n = lut16->numoutchans * lut16->numouttabents; i < n;
1523 if (jas_iccputuint16(out, lut16->outtabsbuf[i]))1693 ++i) {
1694 if (jas_iccputuint16(out, lut16->outtabsbuf[i])) {
1524 goto error;1695 goto error;
1696 }
1525 }1697 }
1526 for (unsigned i = 0, n = jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans; i < n; ++i) {1698 for (unsigned i = 0, n = jas_iccpowi(lut16->clutlen, lut16->numinchans) *
1527 if (jas_iccputuint16(out, lut16->clut[i]))1699 lut16->numoutchans; i < n; ++i) {
1700 if (jas_iccputuint16(out, lut16->clut[i])) {
1528 goto error;1701 goto error;
1702 }
1529 }1703 }
1530 return 0;1704 return 0;
1531error:1705error:
1532 return -1;1706 return -1;
1533}1707}
1534//#endif /* JAS_ENABLE_ENCODER */1708
1709static void jas_icclut16_dump(const jas_iccattrval_t *attrval, FILE *out)
1710{
1711 const jas_icclut16_t *lut16 = &attrval->data.lut16;
1712 fprintf(out, "numinchans=%d, numoutchans=%d, clutlen=%d\n",
1713 lut16->numinchans, lut16->numoutchans, lut16->clutlen);
1714 for (unsigned i = 0; i < 3; ++i) {
1715 for (unsigned j = 0; j < 3; ++j) {
1716 fprintf(out, "e[%d][%d]=%f ", i, j, lut16->e[i][j] / 65536.0);
1717 }
1718 fprintf(out, "\n");
1719 }
1720 fprintf(out, "numintabents=%"PRIuFAST16", numouttabents=%"PRIuFAST16"\n",
1721 lut16->numintabents, lut16->numouttabents);
1722}
1535 1723
1536/******************************************************************************\1724/******************************************************************************\
1537*1725*
@@ -1543,8 +1731,9 @@ static int jas_iccgetuint(jas_stream_t *in, unsigned n, jas_ulonglong *val) · 5 unmodified lines
1543 jas_ulonglong v;1731 jas_ulonglong v;
1544 v = 0;1732 v = 0;
1545 for (unsigned i = n; i > 0; --i) {1733 for (unsigned i = n; i > 0; --i) {
1546 if ((c = jas_stream_getc(in)) == EOF)1734 if ((c = jas_stream_getc(in)) == EOF) {
1547 return -1;1735 return -1;
1736 }
1548 v = (v << 8) | c;1737 v = (v << 8) | c;
1549 }1738 }
1550 *val = v;1739 *val = v;
@@ -1554,8 +1743,9 @@ static int jas_iccgetuint(jas_stream_t *in, unsigned n, jas_ulonglong *val) · 3 unmodified lines
1554static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val)1743static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val)
1555{1744{
1556 int c;1745 int c;
1557 if ((c = jas_stream_getc(in)) == EOF)1746 if ((c = jas_stream_getc(in)) == EOF) {
1558 return -1;1747 return -1;
1748 }
1559 *val = c;1749 *val = c;
1560 return 0;1750 return 0;
1561}1751}
@@ -1563,8 +1753,9 @@ static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val) · 1 unmodified line
1563static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val)1753static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val)
1564{1754{
1565 jas_ulonglong tmp;1755 jas_ulonglong tmp;
1566 if (jas_iccgetuint(in, 2, &tmp))1756 if (jas_iccgetuint(in, 2, &tmp)) {
1567 return -1;1757 return -1;
1758 }
1568 *val = (jas_iccuint16_t)tmp;1759 *val = (jas_iccuint16_t)tmp;
1569 return 0;1760 return 0;
1570}1761}
@@ -1572,8 +1763,9 @@ static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val) · 1 unmodified line
1572static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val)1763static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val)
1573{1764{
1574 jas_ulonglong tmp;1765 jas_ulonglong tmp;
1575 if (jas_iccgetuint(in, 4, &tmp))1766 if (jas_iccgetuint(in, 4, &tmp)) {
1576 return -1;1767 return -1;
1768 }
1577 *val = (tmp & 0x80000000) ? (-JAS_CAST(jas_longlong, (((~tmp) &1769 *val = (tmp & 0x80000000) ? (-JAS_CAST(jas_longlong, (((~tmp) &
1578 0x7fffffff) + 1))) : JAS_CAST(jas_longlong, tmp);1770 0x7fffffff) + 1))) : JAS_CAST(jas_longlong, tmp);
1579 return 0;1771 return 0;
@@ -1582,8 +1774,9 @@ static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val) · 2 unmodified lines
1582static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val)1774static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val)
1583{1775{
1584 jas_ulonglong tmp;1776 jas_ulonglong tmp;
1585 if (jas_iccgetuint(in, 4, &tmp))1777 if (jas_iccgetuint(in, 4, &tmp)) {
1586 return -1;1778 return -1;
1779 }
1587 *val = (jas_iccuint32_t)tmp;1780 *val = (jas_iccuint32_t)tmp;
1588 return 0;1781 return 0;
1589}1782}
@@ -1591,21 +1784,21 @@ static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val) · 1 unmodified line
1591static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val)1784static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val)
1592{1785{
1593 jas_ulonglong tmp;1786 jas_ulonglong tmp;
1594 if (jas_iccgetuint(in, 8, &tmp))1787 if (jas_iccgetuint(in, 8, &tmp)) {
1595 return -1;1788 return -1;
1789 }
1596 *val = (jas_iccuint64_t)tmp;1790 *val = (jas_iccuint64_t)tmp;
1597 return 0;1791 return 0;
1598}1792}
1599 1793
1600//#ifdef JAS_ENABLE_ENCODER
1601
1602static int jas_iccputuint(jas_stream_t *out, unsigned n, jas_ulonglong val)1794static int jas_iccputuint(jas_stream_t *out, unsigned n, jas_ulonglong val)
1603{1795{
1604 int c;1796 int c;
1605 for (unsigned i = n; i > 0; --i) {1797 for (unsigned i = n; i > 0; --i) {
1606 c = (val >> (8 * (i - 1))) & 0xff;1798 c = (val >> (8 * (i - 1))) & 0xff;
1607 if (jas_stream_putc(out, c) == EOF)1799 if (jas_stream_putc(out, c) == EOF) {
1608 return -1;1800 return -1;
1801 }
1609 }1802 }
1610 return 0;1803 return 0;
1611}1804}
@@ -1618,8 +1811,6 @@ static int jas_iccputsint(jas_stream_t *out, unsigned n, jas_longlong val) · 6 unmodified lines
1618 return jas_iccputuint(out, n, tmp);1811 return jas_iccputuint(out, n, tmp);
1619}1812}
1620 1813
1621//#endif /* JAS_ENABLE_ENCODER */
1622
1623/******************************************************************************\1814/******************************************************************************\
1624*1815*
1625\******************************************************************************/1816\******************************************************************************/
@@ -1631,7 +1822,8 @@ static char *jas_iccsigtostr(unsigned sig, char *buf) · 5 unmodified lines
1631 bufptr = buf;1822 bufptr = buf;
1632 for (unsigned n = 4; n > 0; --n) {1823 for (unsigned n = 4; n > 0; --n) {
1633 c = (sig >> 24) & 0xff;1824 c = (sig >> 24) & 0xff;
1634 if (isalpha(c) || isdigit(c)) {1825 if (isalpha(JAS_CAST(unsigned char, c)) ||
1826 isdigit(JAS_CAST(unsigned char, c))) {
1635 *bufptr++ = c;1827 *bufptr++ = c;
1636 }1828 }
1637 sig <<= 8;1829 sig <<= 8;
@@ -1640,36 +1832,40 @@ static char *jas_iccsigtostr(unsigned sig, char *buf) · 2 unmodified lines
1640 return buf;1832 return buf;
1641}1833}
1642 1834
1643//#ifdef JAS_ENABLE_ENCODER
1644static unsigned jas_iccpadtomult(unsigned x, unsigned y)1835static unsigned jas_iccpadtomult(unsigned x, unsigned y)
1645{1836{
1646 return ((x + y - 1) / y) * y;1837 return ((x + y - 1) / y) * y;
1647}1838}
1648//#endif /* JAS_ENABLE_ENCODER */
1649 1839
1650static unsigned jas_iccpowi(unsigned x, unsigned n)1840static unsigned jas_iccpowi(unsigned x, unsigned n)
1651{1841{
1652 unsigned y;1842 unsigned y;
1653 y = 1;1843 y = 1;
1654 while (n-- > 0)1844 while (n-- > 0) {
1655 y *= x;1845 y *= x;
1846 }
1656 return y;1847 return y;
1657}1848}
1658 1849
1659 1850
1660jas_iccprof_t *jas_iccprof_createfrombuf(const jas_uchar *buf, unsigned len)1851jas_iccprof_t *jas_iccprof_createfrombuf(const jas_uchar *buf, unsigned len)
1661{1852{
1853 assert(buf);
1854 assert(len > 0);
1662 jas_stream_t *in;1855 jas_stream_t *in;
1663 jas_iccprof_t *prof;1856 jas_iccprof_t *prof;
1664 if (!(in = jas_stream_memopen(JAS_CAST(char *, buf), len)))1857 if (!(in = jas_stream_memopen(JAS_CAST(char *, buf), len))) {
1665 goto error;1858 goto error;
1666 if (!(prof = jas_iccprof_load(in)))1859 }
1860 if (!(prof = jas_iccprof_load(in))) {
1667 goto error;1861 goto error;
1862 }
1668 jas_stream_close(in);1863 jas_stream_close(in);
1669 return prof;1864 return prof;
1670error:1865error:
1671 if (in)1866 if (in) {
1672 jas_stream_close(in);1867 jas_stream_close(in);
1868 }
1673 return 0;1869 return 0;
1674}1870}
1675 1871
jas_iccdata.c+10−0
@@ -59,9 +59,19 @@ · 58 unmodified lines
59 * __END_OF_JASPER_LICENSE__59 * __END_OF_JASPER_LICENSE__
60 */60 */
61 61
62/******************************************************************************\
63* Includes.
64\******************************************************************************/
65
66//#define JAS_FOR_INTERNAL_USE_ONLY
67
62#include <jasper/jas_config.h> /* IWYU pragma: keep */68#include <jasper/jas_config.h> /* IWYU pragma: keep */
63#include <jasper/jas_types.h>69#include <jasper/jas_types.h>
64 70
71/******************************************************************************\
72* Data.
73\******************************************************************************/
74
65const jas_uchar jas_iccprofdata_srgb[] =75const jas_uchar jas_iccprofdata_srgb[] =
66{76{
67 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f,77 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f,
jas_image.c+404−203
@@ -71,9 +71,13 @@ · 70 unmodified lines
71* Includes.71* Includes.
72\******************************************************************************/72\******************************************************************************/
73 73
74#define JAS_FOR_INTERNAL_USE_ONLY
75
76#include "jasper/jas_init.h"
74#include "jasper/jas_image.h"77#include "jasper/jas_image.h"
75#include "jasper/jas_math.h"78#include "jasper/jas_math.h"
76#include "jasper/jas_malloc.h"79#include "jasper/jas_malloc.h"
80#include "jasper/jas_string.h"
77#include "jasper/jas_debug.h"81#include "jasper/jas_debug.h"
78 82
79/******************************************************************************\83/******************************************************************************\
@@ -90,7 +94,8 @@ static jas_image_cmpt_t *jas_image_cmpt_create0(void); · 10 unmodified lines
90static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt);94static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt);
91static jas_image_cmpt_t *jas_image_cmpt_create(int_fast32_t tlx,95static jas_image_cmpt_t *jas_image_cmpt_create(int_fast32_t tlx,
92 int_fast32_t tly, int_fast32_t hstep, int_fast32_t vstep,96 int_fast32_t tly, int_fast32_t hstep, int_fast32_t vstep,
93 int_fast32_t width, int_fast32_t height, uint_fast16_t depth, bool sgnd);97 int_fast32_t width, int_fast32_t height, uint_fast16_t depth, bool sgnd,
98 bool inmem);
94static void jas_image_setbbox(jas_image_t *image);99static void jas_image_setbbox(jas_image_t *image);
95static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt);100static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt);
96static int jas_image_growcmpts(jas_image_t *image, unsigned maxcmpts);101static int jas_image_growcmpts(jas_image_t *image, unsigned maxcmpts);
@@ -102,30 +107,27 @@ static long uptomult(long x, long y); · 5 unmodified lines
102static long downtomult(long x, long y);107static long downtomult(long x, long y);
103static long convert(long val, bool oldsgnd, unsigned oldprec, bool newsgnd,108static long convert(long val, bool oldsgnd, unsigned oldprec, bool newsgnd,
104 unsigned newprec);109 unsigned newprec);
105static void jas_image_calcbbox2(const jas_image_t *image, jas_image_coord_t *tlx,110static void jas_image_calcbbox2(const jas_image_t *image,
106 jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry);111 jas_image_coord_t *tlx, jas_image_coord_t *tly, jas_image_coord_t *brx,
107 112 jas_image_coord_t *bry);
108/******************************************************************************\113static void jas_image_fmtinfo_init(jas_image_fmtinfo_t *fmtinfo);
109* Global data.114static void jas_image_fmtinfo_cleanup(jas_image_fmtinfo_t *fmtinfo);
110\******************************************************************************/
111
112static unsigned jas_image_numfmts = 0;
113static jas_image_fmtinfo_t jas_image_fmtinfos[JAS_IMAGE_MAXFMTS];
114 115
115/******************************************************************************\116/******************************************************************************\
116* Create and destroy operations.117* Create and destroy operations.
117\******************************************************************************/118\******************************************************************************/
118 119
119jas_image_t *jas_image_create(unsigned numcmpts, const jas_image_cmptparm_t *cmptparms,120jas_image_t *jas_image_create(unsigned numcmpts,
120 jas_clrspc_t clrspc)121 const jas_image_cmptparm_t *cmptparms, jas_clrspc_t clrspc)
121{122{
122 jas_image_t *image;123 jas_image_t *image;
123 size_t rawsize;124 size_t rawsize;
124 unsigned cmptno;125 unsigned cmptno;
125 const jas_image_cmptparm_t *cmptparm;126 const jas_image_cmptparm_t *cmptparm;
126 127
127 JAS_DBGLOG(100, ("jas_image_create(%d, %p, %d)\n", numcmpts, cmptparms,128
128 clrspc));129 JAS_LOGDEBUGF(100, "jas_image_create(%d, %p, %d)\n", numcmpts, cmptparms,
130 clrspc);
129 131
130 if (!(image = jas_image_create0())) {132 if (!(image = jas_image_create0())) {
131 goto error;133 goto error;
@@ -133,6 +135,7 @@ jas_image_t *jas_image_create(unsigned numcmpts, const jas_image_cmptparm_t *cmp · 1 unmodified line
133 135
134 image->clrspc_ = clrspc;136 image->clrspc_ = clrspc;
135 image->maxcmpts_ = numcmpts;137 image->maxcmpts_ = numcmpts;
138// image->inmem_ = true;
136 139
137 /* Allocate memory for the per-component information. */140 /* Allocate memory for the per-component information. */
138 if (!(image->cmpts_ = jas_alloc2(image->maxcmpts_,141 if (!(image->cmpts_ = jas_alloc2(image->maxcmpts_,
@@ -144,6 +147,19 @@ jas_image_t *jas_image_create(unsigned numcmpts, const jas_image_cmptparm_t *cmp · 5 unmodified lines
144 image->cmpts_[cmptno] = 0;147 image->cmpts_[cmptno] = 0;
145 }148 }
146 149
150#if 0
151 /* Compute the approximate raw size of the image. */
152 rawsize = 0;
153 for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno,
154 ++cmptparm) {
155 rawsize += cmptparm->width * cmptparm->height *
156 (cmptparm->prec + 7) / 8;
157 }
158 /* Decide whether to buffer the image data in memory, based on the
159 raw size of the image. */
160 inmem = (rawsize < JAS_IMAGE_INMEMTHRESH);
161#endif
162
147 /* Create the individual image components. */163 /* Create the individual image components. */
148 for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno,164 for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno,
149 ++cmptparm) {165 ++cmptparm) {
@@ -152,10 +168,11 @@ jas_image_t *jas_image_create(unsigned numcmpts, const jas_image_cmptparm_t *cmp · 2 unmodified lines
152 goto error;168 goto error;
153 }169 }
154 rawsize /= 8;170 rawsize /= 8;
171 const bool inmem = (rawsize < JAS_IMAGE_INMEMTHRESH);
155 if (!(image->cmpts_[cmptno] = jas_image_cmpt_create(cmptparm->tlx,172 if (!(image->cmpts_[cmptno] = jas_image_cmpt_create(cmptparm->tlx,
156 cmptparm->tly, cmptparm->hstep, cmptparm->vstep,173 cmptparm->tly, cmptparm->hstep, cmptparm->vstep,
157 cmptparm->width, cmptparm->height, cmptparm->prec,174 cmptparm->width, cmptparm->height, cmptparm->prec,
158 cmptparm->sgnd))) {175 cmptparm->sgnd, inmem))) {
159 goto error;176 goto error;
160 }177 }
161 ++image->numcmpts_;178 ++image->numcmpts_;
@@ -190,6 +207,7 @@ jas_image_t *jas_image_create0() · 28 unmodified lines
190 image->numcmpts_ = 0;207 image->numcmpts_ = 0;
191 image->maxcmpts_ = 0;208 image->maxcmpts_ = 0;
192 image->cmpts_ = 0;209 image->cmpts_ = 0;
210// image->inmem_ = true;
193 image->cmprof_ = 0;211 image->cmprof_ = 0;
194 212
195 return image;213 return image;
@@ -207,7 +225,8 @@ jas_image_t *jas_image_copy(jas_image_t *image) · 11 unmodified lines
207 goto error;225 goto error;
208 }226 }
209 for (unsigned cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {227 for (unsigned cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
210 if (!(newimage->cmpts_[cmptno] = jas_image_cmpt_copy(image->cmpts_[cmptno]))) {228 if (!(newimage->cmpts_[cmptno] = jas_image_cmpt_copy(
229 image->cmpts_[cmptno]))) {
211 goto error;230 goto error;
212 }231 }
213 ++newimage->numcmpts_;232 ++newimage->numcmpts_;
@@ -216,8 +235,9 @@ jas_image_t *jas_image_copy(jas_image_t *image) · 2 unmodified lines
216 jas_image_setbbox(newimage);235 jas_image_setbbox(newimage);
217 236
218 if (image->cmprof_) {237 if (image->cmprof_) {
219 if (!(newimage->cmprof_ = jas_cmprof_copy(image->cmprof_)))238 if (!(newimage->cmprof_ = jas_cmprof_copy(image->cmprof_))) {
220 goto error;239 goto error;
240 }
221 }241 }
222 242
223 return newimage;243 return newimage;
@@ -259,13 +279,13 @@ static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt) · 35 unmodified lines
259 if (!(newcmpt->stream_ = jas_stream_memopen(0, 0))) {279 if (!(newcmpt->stream_ = jas_stream_memopen(0, 0))) {
260 goto error;280 goto error;
261 }281 }
262 if (jas_stream_seek(cmpt->stream_, 0, 0)) {282 if (jas_stream_seek(cmpt->stream_, 0, SEEK_SET)) {
263 goto error;283 goto error;
264 }284 }
265 if (jas_stream_copy(newcmpt->stream_, cmpt->stream_, -1)) {285 if (jas_stream_copy(newcmpt->stream_, cmpt->stream_, -1)) {
266 goto error;286 goto error;
267 }287 }
268 if (jas_stream_seek(newcmpt->stream_, 0, 0)) {288 if (jas_stream_seek(newcmpt->stream_, 0, SEEK_SET)) {
269 goto error;289 goto error;
270 }290 }
271 return newcmpt;291 return newcmpt;
@@ -283,20 +303,22 @@ void jas_image_destroy(jas_image_t *image) · 11 unmodified lines
283 }303 }
284 jas_free(image->cmpts_);304 jas_free(image->cmpts_);
285 }305 }
286 if (image->cmprof_)306 if (image->cmprof_) {
287 jas_cmprof_destroy(image->cmprof_);307 jas_cmprof_destroy(image->cmprof_);
308 }
288 jas_free(image);309 jas_free(image);
289}310}
290 311
291static jas_image_cmpt_t *jas_image_cmpt_create(int_fast32_t tlx,312static jas_image_cmpt_t *jas_image_cmpt_create(int_fast32_t tlx,
292 int_fast32_t tly, int_fast32_t hstep, int_fast32_t vstep,313 int_fast32_t tly, int_fast32_t hstep, int_fast32_t vstep,
293 int_fast32_t width, int_fast32_t height, uint_fast16_t depth, bool sgnd)314 int_fast32_t width, int_fast32_t height, uint_fast16_t depth, bool sgnd,
315 bool inmem)
294{316{
295 jas_image_cmpt_t *cmpt;317 jas_image_cmpt_t *cmpt;
296 size_t size;318 size_t size;
297 319
298 JAS_DBGLOG(100, (320 JAS_LOGDEBUGF(100,
299 "jas_image_cmpt_create(%ld, %ld, %ld, %ld, %ld, %ld, %d, %d)\n",321 "jas_image_cmpt_create(%ld, %ld, %ld, %ld, %ld, %ld, %d, %d, %d)\n",
300 JAS_CAST(long, tlx),322 JAS_CAST(long, tlx),
301 JAS_CAST(long, tly),323 JAS_CAST(long, tly),
302 JAS_CAST(long, hstep),324 JAS_CAST(long, hstep),
@@ -305,7 +327,8 @@ static jas_image_cmpt_t *jas_image_cmpt_create(int_fast32_t tlx, · 2 unmodified lines
305 JAS_CAST(long, height),327 JAS_CAST(long, height),
306 JAS_CAST(int, depth),328 JAS_CAST(int, depth),
307 sgnd,329 sgnd,
308 ));330 inmem
331 );
309 332
310 if (depth < 1U + sgnd) {333 if (depth < 1U + sgnd) {
311 /* we need at least 1 bit for unsigned samples and 2334 /* we need at least 1 bit for unsigned samples and 2
@@ -340,13 +363,16 @@ static jas_image_cmpt_t *jas_image_cmpt_create(int_fast32_t tlx, · 28 unmodified lines
340 cmpt->stream_ = 0;363 cmpt->stream_ = 0;
341 cmpt->cps_ = (depth + 7) / 8;364 cmpt->cps_ = (depth + 7) / 8;
342 365
343 // Compute the number of samples in the image component, while protecting366 /*
344 // against overflow.367 * Compute the number of samples in the image component, while protecting
345 // size = cmpt->width_ * cmpt->height_ * cmpt->cps_;368 * against overflow.
369 * size = cmpt->width_ * cmpt->height_ * cmpt->cps_;
370 */
346 if (!jas_safe_size_mul3(cmpt->width_, cmpt->height_, cmpt->cps_, &size)) {371 if (!jas_safe_size_mul3(cmpt->width_, cmpt->height_, cmpt->cps_, &size)) {
347 goto error;372 goto error;
348 }373 }
349 cmpt->stream_ = jas_stream_memopen2(0, size);374 cmpt->stream_ = (inmem) ? jas_stream_memopen(0, size) :
375 jas_stream_tmpfile();
350 if (!cmpt->stream_) {376 if (!cmpt->stream_) {
351 goto error;377 goto error;
352 }378 }
@@ -358,9 +384,9 @@ static jas_image_cmpt_t *jas_image_cmpt_create(int_fast32_t tlx, · 5 unmodified lines
358 if (size - 1 > LONG_MAX) {384 if (size - 1 > LONG_MAX) {
359 goto error;385 goto error;
360 }386 }
361 if (jas_stream_seek(cmpt->stream_, size - 1, 0) < 0 ||387 if (jas_stream_seek(cmpt->stream_, size - 1, SEEK_SET) < 0 ||
362 jas_stream_putc(cmpt->stream_, 0) == EOF ||388 jas_stream_putc(cmpt->stream_, 0) == EOF ||
363 jas_stream_seek(cmpt->stream_, 0, 0) < 0) {389 jas_stream_seek(cmpt->stream_, 0, SEEK_SET) < 0) {
364 goto error;390 goto error;
365 }391 }
366 }392 }
@@ -393,25 +419,24 @@ jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, const char *optstr) · 26 unmodified lines
393 419
394 /* If possible, try to determine the format of the input data. */420 /* If possible, try to determine the format of the input data. */
395 if (fmt < 0) {421 if (fmt < 0) {
396 if ((fmt = jas_image_getfmt(in)) < 0){422 if ((fmt = jas_image_getfmt(in)) < 0) {
397 werrstr("unknown format");423 jas_logerrorf("jas_image_decode: cannot determine image format\n");
398 goto error;424 goto error;
399 }425 }
400 }426 }
401 427
402 /* Is it possible to decode an image represented in this format? */428 /* Is it possible to decode an image represented in this format? */
403 if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))){429 if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) {
404 werrstr("unsupported format");
405 goto error;430 goto error;
406 }431 }
407 if (!fmtinfo->ops.decode){432 if (!fmtinfo->ops.decode) {
408 werrstr("no decoder for the format");433 jas_logerrorf("jas_image_decode: no decode operation available\n");
409 goto error;434 goto error;
410 }435 }
411 436
412 /* Decode the image. */437 /* Decode the image. */
413 if (!(image = (*fmtinfo->ops.decode)(in, optstr))){438 if (!(image = (*fmtinfo->ops.decode)(in, optstr))) {
414 werrstr("failed to decode");439 jas_logerrorf("jas_image_decode: decode operation failed\n");
415 goto error;440 goto error;
416 }441 }
417 442
@@ -419,16 +444,18 @@ jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, const char *optstr) · 1 unmodified line
419 if (!jas_clrspc_isunknown(image->clrspc_) &&444 if (!jas_clrspc_isunknown(image->clrspc_) &&
420 !jas_clrspc_isgeneric(image->clrspc_) && !image->cmprof_) {445 !jas_clrspc_isgeneric(image->clrspc_) && !image->cmprof_) {
421 if (!(image->cmprof_ =446 if (!(image->cmprof_ =
422 jas_cmprof_createfromclrspc(jas_image_clrspc(image)))){447 jas_cmprof_createfromclrspc(jas_image_clrspc(image)))) {
423 werrstr("failed to create colorspace");448 jas_logerrorf("jas_image_decode: cannot create CM profile\n");
424 goto error;449 goto error;
425 }450 }
426 }451 }
427 452
428 return image;453 return image;
454
429error:455error:
430 if (image)456 if (image) {
431 jas_image_destroy(image);457 jas_image_destroy(image);
458 }
432 return 0;459 return 0;
433}460}
434 461
@@ -437,7 +464,7 @@ int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt, · 2 unmodified lines
437{464{
438 const jas_image_fmtinfo_t *fmtinfo;465 const jas_image_fmtinfo_t *fmtinfo;
439 if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) {466 if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) {
440 jas_eprintf("format lookup failed\n");467 jas_logerrorf("format lookup failed\n");
441 return -1;468 return -1;
442 }469 }
443 return (fmtinfo->ops.encode) ? (*fmtinfo->ops.encode)(image, out,470 return (fmtinfo->ops.encode) ? (*fmtinfo->ops.encode)(image, out,
@@ -460,9 +487,9 @@ int jas_image_readcmpt(jas_image_t *image, unsigned cmptno, jas_image_coord_t x, · 16 unmodified lines
460 jas_seqent_t *dr;487 jas_seqent_t *dr;
461 jas_seqent_t *d;488 jas_seqent_t *d;
462 489
463 JAS_DBGLOG(100, ("jas_image_readcmpt(%p, %d, %ld, %ld, %ld, %ld, %p)\n",490 JAS_LOGDEBUGF(100, "jas_image_readcmpt(%p, %d, %ld, %ld, %ld, %ld, %p)\n",
464 image, cmptno, JAS_CAST(long, x), JAS_CAST(long, y),491 image, cmptno, JAS_CAST(long, x), JAS_CAST(long, y),
465 JAS_CAST(long, width), JAS_CAST(long, height), data));492 JAS_CAST(long, width), JAS_CAST(long, height), data);
466 493
467 if(data == NULL) {494 if(data == NULL) {
468 return -1;495 return -1;
@@ -483,7 +510,8 @@ int jas_image_readcmpt(jas_image_t *image, unsigned cmptno, jas_image_coord_t x, · 14 unmodified lines
483 return -1;510 return -1;
484 }511 }
485 512
486 if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) != width) {513 if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) !=
514 width) {
487 if (jas_matrix_resize(data, height, width)) {515 if (jas_matrix_resize(data, height, width)) {
488 return -1;516 return -1;
489 }517 }
@@ -497,9 +525,13 @@ int jas_image_readcmpt(jas_image_t *image, unsigned cmptno, jas_image_coord_t x, · 7 unmodified lines
497 525
498 dr = jas_matrix_getref(data, 0, 0);526 dr = jas_matrix_getref(data, 0, 0);
499 const uint_least32_t drs = jas_matrix_rowstep(data);527 const uint_least32_t drs = jas_matrix_rowstep(data);
528
529 jas_uchar stack_buffer[16384];
530
500 for (i = 0; i < height; ++i, dr += drs) {531 for (i = 0; i < height; ++i, dr += drs) {
501 d = dr;532 d = dr;
502 if (jas_stream_seek(stream, (cmpt_width * (y + i) + x) * cps, 0) < 0) {533 if (jas_stream_seek(stream, (cmpt_width * (y + i) + x)
534 * cps, SEEK_SET) < 0) {
503 return -1;535 return -1;
504 }536 }
505 537
@@ -507,13 +539,15 @@ int jas_image_readcmpt(jas_image_t *image, unsigned cmptno, jas_image_coord_t x, · 1 unmodified line
507 /* fast path for 1 byte per sample and539 /* fast path for 1 byte per sample and
508 unsigned with bulk reads */540 unsigned with bulk reads */
509 541
510 jas_uchar buffer[16384];542 jas_uchar *buffer = stack_buffer;
511 543
512 if (jas_stream_read(stream, buffer, width) != width)544 if (jas_stream_read(stream, buffer, width) != width) {
513 return -1;545 return -1;
546 }
514 547
515 for (j = 0; j < width; ++j)548 for (j = 0; j < width; ++j) {
516 d[j] = buffer[j];549 d[j] = buffer[j];
550 }
517 551
518 continue;552 continue;
519 }553 }
@@ -533,9 +567,9 @@ int jas_image_readcmpt(jas_image_t *image, unsigned cmptno, jas_image_coord_t x, · 13 unmodified lines
533 return 0;567 return 0;
534}568}
535 569
536int jas_image_writecmpt(jas_image_t *image, unsigned cmptno, jas_image_coord_t x,570int jas_image_writecmpt(jas_image_t *image, unsigned cmptno,
537 jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,571 jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,
538 const jas_matrix_t *data)572 jas_image_coord_t height, const jas_matrix_t *data)
539{573{
540 jas_image_cmpt_t *cmpt;574 jas_image_cmpt_t *cmpt;
541 jas_image_coord_t i;575 jas_image_coord_t i;
@@ -543,9 +577,9 @@ int jas_image_writecmpt(jas_image_t *image, unsigned cmptno, jas_image_coord_t x · 1 unmodified line
543 jas_seqent_t v;577 jas_seqent_t v;
544 int c;578 int c;
545 579
546 JAS_DBGLOG(100, ("jas_image_writecmpt(%p, %d, %ld, %ld, %ld, %ld, %p)\n",580 JAS_LOGDEBUGF(100, "jas_image_writecmpt(%p, %d, %ld, %ld, %ld, %ld, %p)\n",
547 image, cmptno, JAS_CAST(long, x), JAS_CAST(long, y),581 image, cmptno, JAS_CAST(long, x), JAS_CAST(long, y),
548 JAS_CAST(long, width), JAS_CAST(long, height), data));582 JAS_CAST(long, width), JAS_CAST(long, height), data);
549 583
550 if (cmptno >= image->numcmpts_) {584 if (cmptno >= image->numcmpts_) {
551 return -1;585 return -1;
@@ -575,9 +609,13 @@ int jas_image_writecmpt(jas_image_t *image, unsigned cmptno, jas_image_coord_t x · 23 unmodified lines
575 609
576 const jas_seqent_t *dr = jas_matrix_getref(data, 0, 0);610 const jas_seqent_t *dr = jas_matrix_getref(data, 0, 0);
577 const uint_least32_t drs = jas_matrix_rowstep(data);611 const uint_least32_t drs = jas_matrix_rowstep(data);
612
613 jas_uchar stack_buffer[16384];
614
578 for (i = 0; i < height; ++i, dr += drs) {615 for (i = 0; i < height; ++i, dr += drs) {
579 const jas_seqent_t *d = dr;616 const jas_seqent_t *d = dr;
580 if (jas_stream_seek(stream, (cmpt_width * (y + i) + x) * cps, 0) < 0) {617 if (jas_stream_seek(stream, (cmpt_width * (y + i) + x)
618 * cps, SEEK_SET) < 0) {
581 return -1;619 return -1;
582 }620 }
583 621
@@ -585,7 +623,7 @@ int jas_image_writecmpt(jas_image_t *image, unsigned cmptno, jas_image_coord_t x · 1 unmodified line
585 /* fast path for 1 byte per sample and623 /* fast path for 1 byte per sample and
586 unsigned with bulk writes */624 unsigned with bulk writes */
587 625
588 jas_uchar buffer[16384];626 jas_uchar *buffer = stack_buffer;
589 627
590 for (j = 0; j < width; ++j)628 for (j = 0; j < width; ++j)
591 buffer[j] = d[j];629 buffer[j] = d[j];
@@ -614,88 +652,139 @@ int jas_image_writecmpt(jas_image_t *image, unsigned cmptno, jas_image_coord_t x · 22 unmodified lines
614* File format operations.652* File format operations.
615\******************************************************************************/653\******************************************************************************/
616 654
617void jas_image_clearfmts()655static void jas_image_fmtinfo_init(jas_image_fmtinfo_t *fmtinfo)
618{656{
619 jas_image_fmtinfo_t *fmtinfo;657 fmtinfo->id = -1;
620 for (unsigned i = 0; i < jas_image_numfmts; ++i) {658 fmtinfo->name = 0;
621 fmtinfo = &jas_image_fmtinfos[i];659 fmtinfo->ext = 0;
622 if (fmtinfo->name) {660 fmtinfo->exts = 0;
623 jas_free(fmtinfo->name);661 fmtinfo->max_exts = 0;
624 fmtinfo->name = 0;662 fmtinfo->num_exts = 0;
625 }663 fmtinfo->enabled = 0;
626 if (fmtinfo->ext) {664 fmtinfo->desc = 0;
627 jas_free(fmtinfo->ext);665 memset(&fmtinfo->ops, 0, sizeof(jas_image_fmtops_t));
628 fmtinfo->ext = 0;
629 }
630 if (fmtinfo->desc) {
631 jas_free(fmtinfo->desc);
632 fmtinfo->desc = 0;
633 }
634 }
635 jas_image_numfmts = 0;
636}666}
637 667
638int jas_image_addfmt(int id, const char *name, const char *ext,668static void jas_image_fmtinfo_cleanup(jas_image_fmtinfo_t *fmtinfo)
639 const char *desc, const jas_image_fmtops_t *ops)
640{669{
641 jas_image_fmtinfo_t *fmtinfo;670 if (fmtinfo->name) {
642 assert(id >= 0 && name && ext && ops);
643 if (jas_image_numfmts >= JAS_IMAGE_MAXFMTS) {
644 return -1;
645 }
646 fmtinfo = &jas_image_fmtinfos[jas_image_numfmts];
647 fmtinfo->id = id;
648 if (!(fmtinfo->name = strdup(name))) {
649 return -1;
650 }
651 if (!(fmtinfo->ext = strdup(ext))) {
652 jas_free(fmtinfo->name);671 jas_free(fmtinfo->name);
653 return -1;672 fmtinfo->name = 0;
654 }673 }
655 if (!(fmtinfo->desc = strdup(desc))) {674 if (fmtinfo->ext) {
656 jas_free(fmtinfo->name);
657 jas_free(fmtinfo->ext);675 jas_free(fmtinfo->ext);
658 return -1;676 fmtinfo->ext = 0;
659 }677 }
660 fmtinfo->ops = *ops;678 if (fmtinfo->exts) {
661 ++jas_image_numfmts;679 assert(fmtinfo->max_exts > 0);
680 for (int i = 0; i < fmtinfo->num_exts; ++i) {
681 jas_free(fmtinfo->exts[i]);
682 }
683 jas_free(fmtinfo->exts);
684 fmtinfo->exts = 0;
685 }
686 if (fmtinfo->desc) {
687 jas_free(fmtinfo->desc);
688 fmtinfo->desc = 0;
689 }
690}
691
692JAS_EXPORT
693const jas_image_fmtinfo_t *jas_image_getfmtbyind(int index)
694{
695 jas_ctx_t *ctx = jas_get_ctx();
696 assert(index >= 0 && index < ctx->image_numfmts);
697 return &ctx->image_fmtinfos[index];
698}
699
700JAS_EXPORT
701int jas_image_getnumfmts(void)
702{
703 jas_ctx_t *ctx = jas_get_ctx();
704 return ctx->image_numfmts;
705}
706
707JAS_EXPORT
708int jas_image_setfmtenable(int index, int enabled)
709{
710 jas_ctx_t *ctx = jas_get_ctx();
711 ctx->image_fmtinfos[index].enabled = enabled;
662 return 0;712 return 0;
663}713}
664 714
665int jas_image_addcmpt(jas_image_t *image, int cmptno,715void jas_image_clearfmts_internal(jas_image_fmtinfo_t *image_fmtinfos,
666 const jas_image_cmptparm_t *cmptparm)716 size_t *image_numfmts)
667{717{
668 jas_image_cmpt_t *newcmpt;718 jas_image_fmtinfo_t *fmtinfo;
669 if (cmptno < 0) {719 for (int fmtind = 0; fmtind < *image_numfmts; ++fmtind) {
670 cmptno = image->numcmpts_;720 fmtinfo = &image_fmtinfos[fmtind];
721 jas_image_fmtinfo_cleanup(fmtinfo);
671 }722 }
672 assert(cmptno >= 0 && (unsigned)cmptno <= image->numcmpts_);723 *image_numfmts = 0;
673 if (image->numcmpts_ >= image->maxcmpts_) {724}
674 if (jas_image_growcmpts(image, image->maxcmpts_ + 128)) {725
675 return -1;726void jas_image_clearfmts()
676 }727{
728 jas_ctx_t *ctx = jas_get_ctx();
729 jas_image_clearfmts_internal(ctx->image_fmtinfos, &ctx->image_numfmts);
730}
731
732int jas_image_addfmt_internal(jas_image_fmtinfo_t *image_fmtinfos,
733 size_t *image_numfmts, int id, const char *name, const char *ext,
734 const char *desc, const jas_image_fmtops_t *ops)
735{
736 const char delim[] = " \t";
737 int ret = 0;
738 jas_image_fmtinfo_t *fmtinfo = 0;
739
740 assert(id >= 0 && name && ext && ops);
741 if (*image_numfmts >= JAS_IMAGE_MAXFMTS) {
742 ret = -1;
743 goto done;
677 }744 }
678 if (!(newcmpt = jas_image_cmpt_create(cmptparm->tlx,745 fmtinfo = &image_fmtinfos[*image_numfmts];
679 cmptparm->tly, cmptparm->hstep, cmptparm->vstep,746 jas_image_fmtinfo_init(fmtinfo);
680 cmptparm->width, cmptparm->height, cmptparm->prec,747 fmtinfo->id = id;
681 cmptparm->sgnd))) {748 if (jas_stringtokenize(ext, delim, &fmtinfo->exts, &fmtinfo->max_exts,
682 return -1;749 &fmtinfo->num_exts)) {
750 assert(!fmtinfo->exts && !fmtinfo->max_exts && !fmtinfo->num_exts);
751 ret = -1;
752 goto done;
753 }
754 assert(fmtinfo->num_exts > 0);
755 char *primary_ext = fmtinfo->exts[0];
756 if (!(fmtinfo->name = jas_strdup(name))) {
757 ret = -1;
758 goto done;
759 }
760 if (!(fmtinfo->ext = jas_strdup(primary_ext))) {
761 ret = -1;
762 goto done;
763 }
764 if (!(fmtinfo->desc = jas_strdup(desc))) {
765 ret = -1;
766 goto done;
683 }767 }
684 if ((unsigned)cmptno < image->numcmpts_) {768 fmtinfo->ops = *ops;
685 memmove(&image->cmpts_[cmptno + 1], &image->cmpts_[cmptno],769 ++(*image_numfmts);
686 (image->numcmpts_ - (unsigned)cmptno) * sizeof(jas_image_cmpt_t *));770done:
771 if (ret && fmtinfo) {
772 jas_image_fmtinfo_cleanup(fmtinfo);
687 }773 }
688 image->cmpts_[cmptno] = newcmpt;774 return ret;
689 ++image->numcmpts_;775}
690
691 jas_image_setbbox(image);
692 776
693 return 0;777int jas_image_addfmt(int id, const char *name, const char *ext,
778 const char *desc, const jas_image_fmtops_t *ops)
779{
780 jas_ctx_t *ctx = jas_get_ctx();
781 return jas_image_addfmt_internal(ctx->image_fmtinfos, &ctx->image_numfmts,
782 id, name, ext, desc, ops);
694}783}
695 784
696/* This is for future consideration for addition to the library API. */785/* This is for future consideration for addition to the library API. */
697#if 0786#if 0
698JAS_DLLEXPORT787JAS_EXPORT
699int jas_image_delfmt(int fmtid)788int jas_image_delfmt(int fmtid)
700{789{
701 if (fmtid < 0 || fmtid >= JAS_CAST(int, jas_image_numfmts)) {790 if (fmtid < 0 || fmtid >= JAS_CAST(int, jas_image_numfmts)) {
@@ -734,20 +823,21 @@ const char *jas_image_fmttostr(int fmt) · 32 unmodified lines
734 823
735int jas_image_getfmt(jas_stream_t *in)824int jas_image_getfmt(jas_stream_t *in)
736{825{
826 jas_ctx_t *ctx = jas_get_ctx();
737 const jas_image_fmtinfo_t *fmtinfo;827 const jas_image_fmtinfo_t *fmtinfo;
738 828
739 /* Check for data in each of the supported formats. */829 /* Check for data in each of the supported formats. */
740 unsigned i;830 unsigned i;
741 for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i,831 for (i = 0, fmtinfo = ctx->image_fmtinfos; i < ctx->image_numfmts; ++i,
742 ++fmtinfo) {832 ++fmtinfo) {
743 if (fmtinfo->ops.validate) {833 if (fmtinfo->enabled && fmtinfo->ops.validate) {
744 /* Is the input data valid for this format? */834 /* Is the input data valid for this format? */
745 JAS_DBGLOG(20, ("testing for format %s ... ", fmtinfo->name));835 JAS_LOGDEBUGF(20, "testing for format %s\n", fmtinfo->name);
746 if (!(*fmtinfo->ops.validate)(in)) {836 if (!(*fmtinfo->ops.validate)(in)) {
747 JAS_DBGLOG(20, ("test succeeded\n"));837 JAS_LOGDEBUGF(20, "test succeeded\n");
748 return fmtinfo->id;838 return fmtinfo->id;
749 }839 }
750 JAS_DBGLOG(20, ("test failed\n"));840 JAS_LOGDEBUGF(20, "test failed\n");
751 }841 }
752 }842 }
753 return -1;843 return -1;
@@ -755,6 +845,7 @@ int jas_image_getfmt(jas_stream_t *in) · 1 unmodified line
755 845
756int jas_image_fmtfromname(const char *name)846int jas_image_fmtfromname(const char *name)
757{847{
848 jas_ctx_t *ctx = jas_get_ctx();
758 const char *ext;849 const char *ext;
759 const jas_image_fmtinfo_t *fmtinfo;850 const jas_image_fmtinfo_t *fmtinfo;
760 /* Get the file name extension. */851 /* Get the file name extension. */
@@ -764,10 +855,10 @@ int jas_image_fmtfromname(const char *name) · 3 unmodified lines
764 ++ext;855 ++ext;
765 /* Try to find a format that uses this extension. */ 856 /* Try to find a format that uses this extension. */
766 unsigned i;857 unsigned i;
767 for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i,858 for (i = 0, fmtinfo = ctx->image_fmtinfos; i < ctx->image_numfmts; ++i,
768 ++fmtinfo) {859 ++fmtinfo) {
769 /* Do we have a match? */860 /* Do we have a match? */
770 if (!strcmp(ext, fmtinfo->ext)) {861 if (fmtinfo->enabled && !strcmp(ext, fmtinfo->ext)) {
771 return fmtinfo->id;862 return fmtinfo->id;
772 }863 }
773 }864 }
@@ -824,12 +915,45 @@ void jas_image_delcmpt(jas_image_t *image, unsigned cmptno) · 50 unmodified lines
824 jas_image_setbbox(image);915 jas_image_setbbox(image);
825}916}
826 917
918int jas_image_addcmpt(jas_image_t *image, int cmptno,
919 const jas_image_cmptparm_t *cmptparm)
920{
921 jas_image_cmpt_t *newcmpt;
922 if (cmptno < 0) {
923 cmptno = image->numcmpts_;
924 }
925 assert(cmptno >= 0 && (unsigned)cmptno <= image->numcmpts_);
926 if (image->numcmpts_ >= image->maxcmpts_) {
927 if (jas_image_growcmpts(image, image->maxcmpts_ + 128)) {
928 return -1;
929 }
930 }
931 if (!(newcmpt = jas_image_cmpt_create(cmptparm->tlx,
932 cmptparm->tly, cmptparm->hstep, cmptparm->vstep,
933 cmptparm->width, cmptparm->height, cmptparm->prec,
934 cmptparm->sgnd, true))) {
935 return -1;
936 }
937 if ((unsigned)cmptno < image->numcmpts_) {
938 memmove(&image->cmpts_[cmptno + 1], &image->cmpts_[cmptno],
939 (image->numcmpts_ - (unsigned)cmptno) * sizeof(jas_image_cmpt_t *));
940 }
941 image->cmpts_[cmptno] = newcmpt;
942 ++image->numcmpts_;
943
944 jas_image_setbbox(image);
945
946 return 0;
947}
948
827const jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id)949const jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id)
828{950{
951 jas_ctx_t *ctx = jas_get_ctx();
829 unsigned i;952 unsigned i;
830 const jas_image_fmtinfo_t *fmtinfo;953 const jas_image_fmtinfo_t *fmtinfo;
831 954
832 for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, ++fmtinfo) {955 for (i = 0, fmtinfo = ctx->image_fmtinfos; i < ctx->image_numfmts;
956 ++i, ++fmtinfo) {
833 if (fmtinfo->id == id) {957 if (fmtinfo->id == id) {
834 return fmtinfo;958 return fmtinfo;
835 }959 }
@@ -839,10 +963,11 @@ const jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id) · 3 unmodified lines
839 963
840const jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name)964const jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name)
841{965{
966 jas_ctx_t *ctx = jas_get_ctx();
842 unsigned i;967 unsigned i;
843 const jas_image_fmtinfo_t *fmtinfo;968 const jas_image_fmtinfo_t *fmtinfo;
844 969 for (i = 0, fmtinfo = ctx->image_fmtinfos; i < ctx->image_numfmts;
845 for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, ++fmtinfo) {970 ++i, ++fmtinfo) {
846 if (!strcmp(fmtinfo->name, name)) {971 if (!strcmp(fmtinfo->name, name)) {
847 return fmtinfo;972 return fmtinfo;
848 }973 }
@@ -853,7 +978,9 @@ const jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name) · 4 unmodified lines
853static uint_fast32_t inttobits(jas_seqent_t v, unsigned prec, bool sgnd)978static uint_fast32_t inttobits(jas_seqent_t v, unsigned prec, bool sgnd)
854{979{
855 uint_fast32_t ret;980 uint_fast32_t ret;
856 ret = ((sgnd && v < 0) ? ((1 << prec) + v) : v) & JAS_ONES(prec);981 assert(v >= 0 || sgnd);
982 ret = ((sgnd && v < 0) ? (JAS_POW2_X(jas_seqent_t, prec) + v) : v) &
983 JAS_ONES(prec);
857 return ret;984 return ret;
858}985}
859 986
@@ -945,8 +1072,39 @@ int jas_image_copycmpt(jas_image_t *dstimage, unsigned dstcmptno, · 85 unmodified lines
945 return 0;1072 return 0;
946}1073}
947 1074
948int jas_image_depalettize(jas_image_t *image, unsigned cmptno, unsigned numlutents,1075int jas_image_dump(jas_image_t *image, FILE *out)
949 const int_fast32_t *lutents, unsigned dtype, unsigned newcmptno)1076{
1077 long buf[1024];
1078 jas_image_cmpt_t *cmpt;
1079 for (unsigned cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
1080 cmpt = image->cmpts_[cmptno];
1081 fprintf(out, "prec=%d, sgnd=%d, cmpttype=%"PRIiFAST32"\n", cmpt->prec_,
1082 cmpt->sgnd_, cmpt->type_);
1083 const unsigned width = jas_image_cmptwidth(image, cmptno);
1084 const unsigned height = jas_image_cmptheight(image, cmptno);
1085 const unsigned n = JAS_MIN(16, width);
1086 if (jas_image_readcmpt2(image, cmptno, 0, 0, n, 1, buf)) {
1087 return -1;
1088 }
1089 for (unsigned i = 0; i < n; ++i) {
1090 fprintf(out, " f(%d,%d)=%ld", i, 0, buf[i]);
1091 }
1092 fprintf(out, "\n");
1093 if (jas_image_readcmpt2(image, cmptno, width - n, height - 1, n, 1,
1094 buf)) {
1095 return -1;
1096 }
1097 for (unsigned i = 0; i < n; ++i) {
1098 fprintf(out, " f(%d,%d)=%ld", width - n + i, height - 1, buf[i]);
1099 }
1100 fprintf(out, "\n");
1101 }
1102 return 0;
1103}
1104
1105int jas_image_depalettize(jas_image_t *image, unsigned cmptno,
1106 unsigned numlutents, const int_fast32_t *lutents, unsigned dtype,
1107 unsigned newcmptno)
950{1108{
951 jas_image_cmptparm_t cmptparms;1109 jas_image_cmptparm_t cmptparms;
952 const jas_image_cmpt_t *cmpt = image->cmpts_[cmptno];1110 const jas_image_cmpt_t *cmpt = image->cmpts_[cmptno];
@@ -994,7 +1152,8 @@ int jas_image_readcmptsample(jas_image_t *image, unsigned cmptno, unsigned x, un · 41 unmodified lines
994 1152
995 cmpt = image->cmpts_[cmptno];1153 cmpt = image->cmpts_[cmptno];
996 1154
997 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_, 0) < 0) {1155 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_,
1156 SEEK_SET) < 0) {
998 return -1;1157 return -1;
999 }1158 }
1000 v = 0;1159 v = 0;
@@ -1016,7 +1175,8 @@ void jas_image_writecmptsample(jas_image_t *image, unsigned cmptno, unsigned x, · 15 unmodified lines
1016 1175
1017 cmpt = image->cmpts_[cmptno];1176 cmpt = image->cmpts_[cmptno];
1018 1177
1019 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_, 0) < 0) {1178 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_,
1179 SEEK_SET) < 0) {
1020 return;1180 return;
1021 }1181 }
1022 t = inttobits(v, cmpt->prec_, cmpt->sgnd_);1182 t = inttobits(v, cmpt->prec_, cmpt->sgnd_);
@@ -1029,7 +1189,8 @@ void jas_image_writecmptsample(jas_image_t *image, unsigned cmptno, unsigned x, · 6 unmodified lines
1029 }1189 }
1030}1190}
1031 1191
1032int jas_image_getcmptbytype(const jas_image_t *image, jas_image_cmpttype_t ctype)1192int jas_image_getcmptbytype(const jas_image_t *image,
1193 jas_image_cmpttype_t ctype)
1033{1194{
1034 for (unsigned cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {1195 for (unsigned cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
1035 if (image->cmpts_[cmptno]->type_ == ctype) {1196 if (image->cmpts_[cmptno]->type_ == ctype) {
@@ -1039,29 +1200,14 @@ int jas_image_getcmptbytype(const jas_image_t *image, jas_image_cmpttype_t ctype · 3 unmodified lines
1039 return -1;1200 return -1;
1040}1201}
1041 1202
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057/***********************************************/1203/***********************************************/
1058/***********************************************/1204/***********************************************/
1059/***********************************************/1205/***********************************************/
1060/***********************************************/1206/***********************************************/
1061 1207
1062int jas_image_readcmpt2(jas_image_t *image, unsigned cmptno, jas_image_coord_t x,1208int jas_image_readcmpt2(jas_image_t *image, unsigned cmptno,
1063 jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,1209 jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,
1064 long *buf)1210 jas_image_coord_t height, long *buf)
1065{1211{
1066 jas_image_cmpt_t *cmpt;1212 jas_image_cmpt_t *cmpt;
1067 jas_image_coord_t i;1213 jas_image_coord_t i;
@@ -1069,21 +1215,26 @@ int jas_image_readcmpt2(jas_image_t *image, unsigned cmptno, jas_image_coord_t x · 1 unmodified line
1069 long v;1215 long v;
1070 long *bufptr;1216 long *bufptr;
1071 1217
1072 if (cmptno >= image->numcmpts_)1218 if (cmptno >= image->numcmpts_) {
1073 goto error;1219 goto error;
1220 }
1074 cmpt = image->cmpts_[cmptno];1221 cmpt = image->cmpts_[cmptno];
1075 if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ ||1222 if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ ||
1076 width < 0 || height < 0 || x + width > cmpt->width_ ||1223 width < 0 || height < 0 || x + width > cmpt->width_ ||
1077 y + height > cmpt->height_)1224 y + height > cmpt->height_) {
1078 goto error;1225 goto error;
1226 }
1079 1227
1080 bufptr = buf;1228 bufptr = buf;
1081 for (i = 0; i < height; ++i) {1229 for (i = 0; i < height; ++i) {
1082 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) * cmpt->cps_, 0) < 0)1230 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x)
1231 * cmpt->cps_, SEEK_SET) < 0) {
1083 goto error;1232 goto error;
1233 }
1084 for (j = 0; j < width; ++j) {1234 for (j = 0; j < width; ++j) {
1085 if (getint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, &v))1235 if (getint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, &v)) {
1086 goto error;1236 goto error;
1237 }
1087 *bufptr++ = v;1238 *bufptr++ = v;
1088 }1239 }
1089 }1240 }
@@ -1093,31 +1244,36 @@ error: · 3 unmodified lines
1093 return -1;1244 return -1;
1094}1245}
1095 1246
1096int jas_image_writecmpt2(jas_image_t *image, unsigned cmptno, jas_image_coord_t x,1247int jas_image_writecmpt2(jas_image_t *image, unsigned cmptno,
1097 jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,1248 jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,
1098 const long *buf)1249 jas_image_coord_t height, const long *buf)
1099{1250{
1100 jas_image_cmpt_t *cmpt;1251 jas_image_cmpt_t *cmpt;
1101 jas_image_coord_t i;1252 jas_image_coord_t i;
1102 jas_image_coord_t j;1253 jas_image_coord_t j;
1103 long v;1254 long v;
1104 1255
1105 if (cmptno >= image->numcmpts_)1256 if (cmptno >= image->numcmpts_) {
1106 goto error;1257 goto error;
1258 }
1107 cmpt = image->cmpts_[cmptno];1259 cmpt = image->cmpts_[cmptno];
1108 if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ ||1260 if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ ||
1109 width < 0 || height < 0 || x + width > cmpt->width_ ||1261 width < 0 || height < 0 || x + width > cmpt->width_ ||
1110 y + height > cmpt->height_)1262 y + height > cmpt->height_) {
1111 goto error;1263 goto error;
1264 }
1112 1265
1113 const long *bufptr = buf;1266 const long *bufptr = buf;
1114 for (i = 0; i < height; ++i) {1267 for (i = 0; i < height; ++i) {
1115 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) * cmpt->cps_, 0) < 0)1268 if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x)
1269 * cmpt->cps_, SEEK_SET) < 0) {
1116 goto error;1270 goto error;
1271 }
1117 for (j = 0; j < width; ++j) {1272 for (j = 0; j < width; ++j) {
1118 v = *bufptr++;1273 v = *bufptr++;
1119 if (putint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, v))1274 if (putint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, v)) {
1120 goto error;1275 goto error;
1276 }
1121 }1277 }
1122 }1278 }
1123 1279
@@ -1165,10 +1321,11 @@ int jas_image_sampcmpt(jas_image_t *image, unsigned cmptno, unsigned newcmptno, · 41 unmodified lines
1165 cmptparm.height = height;1321 cmptparm.height = height;
1166 cmptparm.prec = prec;1322 cmptparm.prec = prec;
1167 cmptparm.sgnd = sgnd;1323 cmptparm.sgnd = sgnd;
1168 if (jas_image_addcmpt(image, newcmptno, &cmptparm))1324 if (jas_image_addcmpt(image, newcmptno, &cmptparm)) {
1169 goto error;1325 goto error;
1170cmptbrx = oldcmpt->tlx_ + (oldcmpt->width_ - 1) * oldcmpt->hstep_;1326 }
1171cmptbry = oldcmpt->tly_ + (oldcmpt->height_ - 1) * oldcmpt->vstep_;1327 cmptbrx = oldcmpt->tlx_ + (oldcmpt->width_ - 1) * oldcmpt->hstep_;
1328 cmptbry = oldcmpt->tly_ + (oldcmpt->height_ - 1) * oldcmpt->vstep_;
1172 const jas_image_cmpt_t *const newcmpt = image->cmpts_[newcmptno];1329 const jas_image_cmpt_t *const newcmpt = image->cmpts_[newcmptno];
1173 jas_stream_rewind(newcmpt->stream_);1330 jas_stream_rewind(newcmpt->stream_);
1174 for (unsigned i = 0; i < height; ++i) {1331 for (unsigned i = 0; i < height; ++i) {
@@ -1178,11 +1335,13 @@ cmptbry = oldcmpt->tly_ + (oldcmpt->height_ - 1) * oldcmpt->vstep_; · 3 unmodified lines
1178 ax = downtomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_;1335 ax = downtomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_;
1179 ay = downtomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_;1336 ay = downtomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_;
1180 bx = uptomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_;1337 bx = uptomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_;
1181 if (bx > cmptbrx)1338 if (bx > cmptbrx) {
1182 bx = cmptbrx;1339 bx = cmptbrx;
1340 }
1183 by = uptomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_;1341 by = uptomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_;
1184 if (by > cmptbry)1342 if (by > cmptbry) {
1185 by = cmptbry;1343 by = cmptbry;
1344 }
1186 d0 = (ax - x) * (ax - x) + (ay - y) * (ay - y);1345 d0 = (ax - x) * (ax - x) + (ay - y) * (ay - y);
1187 d1 = (bx - x) * (bx - x) + (ay - y) * (ay - y);1346 d1 = (bx - x) * (bx - x) + (ay - y) * (ay - y);
1188 d2 = (bx - x) * (bx - x) + (by - y) * (by - y);1347 d2 = (bx - x) * (bx - x) + (by - y) * (by - y);
@@ -1202,19 +1361,23 @@ cmptbry = oldcmpt->tly_ + (oldcmpt->height_ - 1) * oldcmpt->vstep_; · 13 unmodified lines
1202 }1361 }
1203 assert(oldx >= 0 && oldx < oldcmpt->width_ &&1362 assert(oldx >= 0 && oldx < oldcmpt->width_ &&
1204 oldy >= 0 && oldy < oldcmpt->height_);1363 oldy >= 0 && oldy < oldcmpt->height_);
1205 if (jas_stream_seek(oldcmpt->stream_, oldcmpt->cps_ * (oldy * oldcmpt->width_ + oldx), 0) < 0)1364 if (jas_stream_seek(oldcmpt->stream_, oldcmpt->cps_ *
1365 (oldy * oldcmpt->width_ + oldx), SEEK_SET) < 0) {
1206 goto error;1366 goto error;
1367 }
1207 if (getint(oldcmpt->stream_, oldcmpt->sgnd_,1368 if (getint(oldcmpt->stream_, oldcmpt->sgnd_,
1208 oldcmpt->prec_, &v))1369 oldcmpt->prec_, &v)) {
1209 goto error;1370 goto error;
1371 }
1210 if (newcmpt->prec_ != oldcmpt->prec_ ||1372 if (newcmpt->prec_ != oldcmpt->prec_ ||
1211 newcmpt->sgnd_ != oldcmpt->sgnd_) {1373 newcmpt->sgnd_ != oldcmpt->sgnd_) {
1212 v = convert(v, oldcmpt->sgnd_, oldcmpt->prec_,1374 v = convert(v, oldcmpt->sgnd_, oldcmpt->prec_,
1213 newcmpt->sgnd_, newcmpt->prec_);1375 newcmpt->sgnd_, newcmpt->prec_);
1214 }1376 }
1215 if (putint(newcmpt->stream_, newcmpt->sgnd_,1377 if (putint(newcmpt->stream_, newcmpt->sgnd_,
1216 newcmpt->prec_, v))1378 newcmpt->prec_, v)) {
1217 goto error;1379 goto error;
1380 }
1218 }1381 }
1219 }1382 }
1220 return 0;1383 return 0;
@@ -1241,8 +1404,9 @@ int jas_image_ishomosamp(const jas_image_t *image) · 20 unmodified lines
1241}1404}
1242 1405
1243/* Note: This function defines a bounding box differently. */1406/* Note: This function defines a bounding box differently. */
1244static void jas_image_calcbbox2(const jas_image_t *image, jas_image_coord_t *tlx,1407static void jas_image_calcbbox2(const jas_image_t *image,
1245 jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry)1408 jas_image_coord_t *tlx, jas_image_coord_t *tly, jas_image_coord_t *brx,
1409 jas_image_coord_t *bry)
1246{1410{
1247 jas_image_coord_t tmptlx;1411 jas_image_coord_t tmptlx;
1248 jas_image_coord_t tmptly;1412 jas_image_coord_t tmptly;
@@ -1257,16 +1421,20 @@ static void jas_image_calcbbox2(const jas_image_t *image, jas_image_coord_t *tlx · 8 unmodified lines
1257 tmpbry = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1);1421 tmpbry = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1);
1258 for (unsigned i = 0; i < image->numcmpts_; ++i) {1422 for (unsigned i = 0; i < image->numcmpts_; ++i) {
1259 cmpt = image->cmpts_[i];1423 cmpt = image->cmpts_[i];
1260 if (cmpt->tlx_ < tmptlx)1424 if (cmpt->tlx_ < tmptlx) {
1261 tmptlx = cmpt->tlx_;1425 tmptlx = cmpt->tlx_;
1262 if (cmpt->tly_ < tmptly)1426 }
1427 if (cmpt->tly_ < tmptly) {
1263 tmptly = cmpt->tly_;1428 tmptly = cmpt->tly_;
1429 }
1264 t = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1);1430 t = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1);
1265 if (t > tmpbrx)1431 if (t > tmpbrx) {
1266 tmpbrx = t;1432 tmpbrx = t;
1433 }
1267 t = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1);1434 t = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1);
1268 if (t > tmpbry)1435 if (t > tmpbry) {
1269 tmpbry = t;1436 tmpbry = t;
1437 }
1270 }1438 }
1271 } else {1439 } else {
1272 tmptlx = 0;1440 tmptlx = 0;
@@ -1285,7 +1453,7 @@ static inline long decode_twos_comp(jas_ulong c, unsigned prec) · 12 unmodified lines
1285{1453{
1286 long result;1454 long result;
1287 assert(prec >= 2);1455 assert(prec >= 2);
1288 jas_eprintf("warning: support for signed data is untested\n");1456 jas_logwarnf("warning: support for signed data is untested\n");
1289 // NOTE: Is this correct?1457 // NOTE: Is this correct?
1290 result = (c & ((1 << (prec - 1)) - 1)) - (c & (1 << (prec - 1)));1458 result = (c & ((1 << (prec - 1)) - 1)) - (c & (1 << (prec - 1)));
1291 return result;1459 return result;
@@ -1296,7 +1464,7 @@ static inline jas_ulong encode_twos_comp(long n, unsigned prec) · 4 unmodified lines
1296{1464{
1297 jas_ulong result;1465 jas_ulong result;
1298 assert(prec >= 2);1466 assert(prec >= 2);
1299 jas_eprintf("warning: support for signed data is untested\n");1467 jas_logwarnf("warning: support for signed data is untested\n");
1300 // NOTE: Is this correct?1468 // NOTE: Is this correct?
1301 if (n < 0) {1469 if (n < 0) {
1302 result = -n;1470 result = -n;
@@ -1315,8 +1483,9 @@ static int getint(jas_stream_t *in, bool sgnd, unsigned prec, long *val) · 12 unmodified lines
1315 assert((!sgnd && prec >= 1) || (sgnd && prec >= 2));1483 assert((!sgnd && prec >= 1) || (sgnd && prec >= 2));
1316 v = 0;1484 v = 0;
1317 for (unsigned n = (prec + 7) / 8; n-- > 0;) {1485 for (unsigned n = (prec + 7) / 8; n-- > 0;) {
1318 if ((c = jas_stream_getc(in)) == EOF)1486 if ((c = jas_stream_getc(in)) == EOF) {
1319 return -1;1487 return -1;
1488 }
1320 v = (v << 8) | c;1489 v = (v << 8) | c;
1321 }1490 }
1322 v &= ((1 << prec) - 1);1491 v &= ((1 << prec) - 1);
@@ -1339,8 +1508,9 @@ static int putint(jas_stream_t *out, bool sgnd, unsigned prec, long val) · 16 unmodified lines
1339 val &= (1 << prec) - 1;1508 val &= (1 << prec) - 1;
1340 for (unsigned n = (prec + 7) / 8; n-- > 0;) {1509 for (unsigned n = (prec + 7) / 8; n-- > 0;) {
1341 c = (val >> (n * 8)) & 0xff;1510 c = (val >> (n * 8)) & 0xff;
1342 if (jas_stream_putc(out, c) != c)1511 if (jas_stream_putc(out, c) != c) {
1343 return -1;1512 return -1;
1513 }
1344 }1514 }
1345 return 0;1515 return 0;
1346}1516}
@@ -1348,6 +1518,7 @@ static int putint(jas_stream_t *out, bool sgnd, unsigned prec, long val) · 1 unmodified line
1348static long convert(long val, bool oldsgnd, unsigned oldprec, bool newsgnd,1518static long convert(long val, bool oldsgnd, unsigned oldprec, bool newsgnd,
1349 unsigned newprec)1519 unsigned newprec)
1350{1520{
1521 /* TODO: The following code looks suspicious (i.e., an empty if body). */
1351 if (newsgnd != oldsgnd) {1522 if (newsgnd != oldsgnd) {
1352 }1523 }
1353 if (newprec != oldprec) {1524 if (newprec != oldprec) {
@@ -1372,8 +1543,8 @@ static long uptomult(long x, long y) · 18 unmodified lines
1372 return ((x + y - 1) / y) * y;1543 return ((x + y - 1) / y) * y;
1373}1544}
1374 1545
1375jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof,1546jas_image_t *jas_image_chclrspc(jas_image_t *image,
1376 jas_cmxform_intent_t intent)1547 const jas_cmprof_t *outprof, jas_cmxform_intent_t intent)
1377{1548{
1378 jas_image_t *inimage;1549 jas_image_t *inimage;
1379 int k;1550 int k;
@@ -1387,16 +1558,25 @@ jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof, · 7 unmodified lines
1387 jas_cmcmptfmt_t *incmptfmts;1558 jas_cmcmptfmt_t *incmptfmts;
1388 jas_cmcmptfmt_t *outcmptfmts;1559 jas_cmcmptfmt_t *outcmptfmts;
1389 1560
1390 if (image->numcmpts_ == 0)1561#if 0
1391 /* can't work with a file with no components;1562 jas_eprintf("IMAGE\n");
1392 continuing would crash because we'd attempt to1563 jas_image_dump(image, stderr);
1393 obtain information about the first component */1564#endif
1394 return NULL;1565
1566 if (image->numcmpts_ == 0) {
1567 /*
1568 can't work with a file with no components;
1569 continuing would crash because we'd attempt to
1570 obtain information about the first component
1571 */
1572 return 0;
1573 }
1395 1574
1396 outimage = 0;1575 outimage = 0;
1397 xform = 0;1576 xform = 0;
1398 if (!(inimage = jas_image_copy(image)))1577 if (!(inimage = jas_image_copy(image))) {
1399 goto error;1578 goto error;
1579 }
1400 1580
1401 if (!jas_image_ishomosamp(inimage)) {1581 if (!jas_image_ishomosamp(inimage)) {
1402 unsigned minhstep = jas_image_cmpthstep(inimage, 0);1582 unsigned minhstep = jas_image_cmpthstep(inimage, 0);
@@ -1414,10 +1594,12 @@ jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof, · 11 unmodified lines
1414 unsigned n = jas_image_numcmpts(inimage);1594 unsigned n = jas_image_numcmpts(inimage);
1415 for (unsigned i = 0; i < n; ++i) {1595 for (unsigned i = 0; i < n; ++i) {
1416 if (jas_image_sampcmpt(inimage, i, i + 1, 0, 0, minhstep, minvstep,1596 if (jas_image_sampcmpt(inimage, i, i + 1, 0, 0, minhstep, minvstep,
1417 jas_image_cmptsgnd(inimage, i), jas_image_cmptprec(inimage, i))) {1597 jas_image_cmptsgnd(inimage, i), jas_image_cmptprec(inimage,
1598 i))) {
1418 goto error;1599 goto error;
1419 }1600 }
1420 const jas_image_cmpttype_t cmpttype = jas_image_cmpttype(inimage, i);1601 const jas_image_cmpttype_t cmpttype = jas_image_cmpttype(inimage,
1602 i);
1421 jas_image_setcmpttype(inimage, i + 1, cmpttype);1603 jas_image_setcmpttype(inimage, i + 1, cmpttype);
1422 jas_image_delcmpt(inimage, i);1604 jas_image_delcmpt(inimage, i);
1423 }1605 }
@@ -1429,10 +1611,13 @@ jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof, · 5 unmodified lines
1429 const unsigned vstep = jas_image_cmptvstep(inimage, 0);1611 const unsigned vstep = jas_image_cmptvstep(inimage, 0);
1430 1612
1431 if (!(inprof = jas_image_cmprof(inimage))) {1613 if (!(inprof = jas_image_cmprof(inimage))) {
1432 abort();1614 // formerly call to abort()
1615 goto error;
1433 }1616 }
1434 const unsigned numinclrchans = jas_clrspc_numchans(jas_cmprof_clrspc(inprof));1617 const unsigned numinclrchans =
1435 const unsigned numoutclrchans = jas_clrspc_numchans(jas_cmprof_clrspc(outprof));1618 jas_clrspc_numchans(jas_cmprof_clrspc(inprof));
1619 const unsigned numoutclrchans =
1620 jas_clrspc_numchans(jas_cmprof_clrspc(outprof));
1436 const unsigned prec = 8;1621 const unsigned prec = 8;
1437 1622
1438 if (!(outimage = jas_image_create0())) {1623 if (!(outimage = jas_image_create0())) {
@@ -1449,8 +1634,9 @@ jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof, · 10 unmodified lines
1449 cmptparm.height = height;1634 cmptparm.height = height;
1450 cmptparm.prec = prec;1635 cmptparm.prec = prec;
1451 cmptparm.sgnd = 0;1636 cmptparm.sgnd = 0;
1452 if (jas_image_addcmpt(outimage, -1, &cmptparm))1637 if (jas_image_addcmpt(outimage, -1, &cmptparm)) {
1453 goto error;1638 goto error;
1639 }
1454 jas_image_setcmpttype(outimage, i, JAS_IMAGE_CT_COLOR(i));1640 jas_image_setcmpttype(outimage, i, JAS_IMAGE_CT_COLOR(i));
1455 }1641 }
1456#if 01642#if 0
@@ -1463,8 +1649,9 @@ jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof, · 6 unmodified lines
1463 }1649 }
1464#endif1650#endif
1465 1651
1466 if (!(tmpprof = jas_cmprof_copy(outprof)))1652 if (!(tmpprof = jas_cmprof_copy(outprof))) {
1467 goto error;1653 goto error;
1654 }
1468 assert(!jas_image_cmprof(outimage));1655 assert(!jas_image_cmprof(outimage));
1469 jas_image_setcmprof(outimage, tmpprof);1656 jas_image_setcmprof(outimage, tmpprof);
1470 jas_image_setclrspc(outimage, jas_cmprof_clrspc(outprof));1657 jas_image_setclrspc(outimage, jas_cmprof_clrspc(outprof));
@@ -1476,7 +1663,8 @@ jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof, · 5 unmodified lines
1476 1663
1477 inpixmap.numcmpts = numinclrchans;1664 inpixmap.numcmpts = numinclrchans;
1478 if (!(incmptfmts = jas_alloc2(numinclrchans, sizeof(jas_cmcmptfmt_t)))) {1665 if (!(incmptfmts = jas_alloc2(numinclrchans, sizeof(jas_cmcmptfmt_t)))) {
1479 abort();1666 // formerly call to abort()
1667 goto error;
1480 }1668 }
1481 inpixmap.cmptfmts = incmptfmts;1669 inpixmap.cmptfmts = incmptfmts;
1482 for (unsigned i = 0; i < numinclrchans; ++i) {1670 for (unsigned i = 0; i < numinclrchans; ++i) {
@@ -1492,14 +1680,16 @@ jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof, · 9 unmodified lines
1492 1680
1493 outpixmap.numcmpts = numoutclrchans;1681 outpixmap.numcmpts = numoutclrchans;
1494 if (!(outcmptfmts = jas_alloc2(numoutclrchans, sizeof(jas_cmcmptfmt_t)))) {1682 if (!(outcmptfmts = jas_alloc2(numoutclrchans, sizeof(jas_cmcmptfmt_t)))) {
1495 abort();1683 // formerly call to abort()
1684 goto error;
1496 }1685 }
1497 outpixmap.cmptfmts = outcmptfmts;1686 outpixmap.cmptfmts = outcmptfmts;
1498 1687
1499 for (unsigned i = 0; i < numoutclrchans; ++i) {1688 for (unsigned i = 0; i < numoutclrchans; ++i) {
1500 const int j = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(i));1689 const int j = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(i));
1501 if (!(outcmptfmts[i].buf = jas_alloc2(width, sizeof(long))))1690 if (!(outcmptfmts[i].buf = jas_alloc2(width, sizeof(long)))) {
1502 goto error;1691 goto error;
1692 }
1503 outcmptfmts[i].prec = jas_image_cmptprec(outimage, j);1693 outcmptfmts[i].prec = jas_image_cmptprec(outimage, j);
1504 outcmptfmts[i].sgnd = jas_image_cmptsgnd(outimage, j);1694 outcmptfmts[i].sgnd = jas_image_cmptsgnd(outimage, j);
1505 outcmptfmts[i].width = width;1695 outcmptfmts[i].width = width;
@@ -1510,15 +1700,17 @@ jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof, · 4 unmodified lines
1510 for (unsigned j = 0; j < numinclrchans; ++j) {1700 for (unsigned j = 0; j < numinclrchans; ++j) {
1511 k = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(j));1701 k = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(j));
1512 if (jas_image_readcmpt2(inimage, k, 0, i, width, 1,1702 if (jas_image_readcmpt2(inimage, k, 0, i, width, 1,
1513 incmptfmts[j].buf))1703 incmptfmts[j].buf)) {
1514 goto error;1704 goto error;
1705 }
1515 }1706 }
1516 jas_cmxform_apply(xform, &inpixmap, &outpixmap);1707 jas_cmxform_apply(xform, &inpixmap, &outpixmap);
1517 for (unsigned j = 0; j < numoutclrchans; ++j) {1708 for (unsigned j = 0; j < numoutclrchans; ++j) {
1518 k = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(j));1709 k = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(j));
1519 if (jas_image_writecmpt2(outimage, k, 0, i, width, 1,1710 if (jas_image_writecmpt2(outimage, k, 0, i, width, 1,
1520 outcmptfmts[j].buf))1711 outcmptfmts[j].buf)) {
1521 goto error;1712 goto error;
1713 }
1522 }1714 }
1523 }1715 }
1524 1716
@@ -1533,13 +1725,22 @@ jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof, · 8 unmodified lines
1533 jas_cmxform_destroy(xform);1725 jas_cmxform_destroy(xform);
1534 jas_image_destroy(inimage);1726 jas_image_destroy(inimage);
1535 1727
1728#if 0
1729 jas_eprintf("INIMAGE\n");
1730 jas_image_dump(inimage, stderr);
1731 jas_eprintf("OUTIMAGE\n");
1732 jas_image_dump(outimage, stderr);
1733#endif
1536 return outimage;1734 return outimage;
1537error:1735error:
1538 if (xform)1736 if (xform) {
1539 jas_cmxform_destroy(xform);1737 jas_cmxform_destroy(xform);
1540 if (inimage)1738 }
1739 if (inimage) {
1541 jas_image_destroy(inimage);1740 jas_image_destroy(inimage);
1542 if (outimage)1741 }
1742 if (outimage) {
1543 jas_image_destroy(outimage);1743 jas_image_destroy(outimage);
1744 }
1544 return 0;1745 return 0;
1545}1746}
jas_init.c+949−23
@@ -63,45 +63,971 @@ · 62 unmodified lines
63* Includes.63* Includes.
64\******************************************************************************/64\******************************************************************************/
65 65
66#define JAS_FOR_INTERNAL_USE_ONLY
67
66#include "jasper/jas_init.h"68#include "jasper/jas_init.h"
67#include "jasper/jas_image.h"69#include "jasper/jas_image.h"
70#include "jasper/jas_malloc.h"
71#include "jasper/jas_debug.h"
72#include "jasper/jas_string.h"
73#include "jasper/jas_thread.h"
74
75/******************************************************************************\
76* Types.
77\******************************************************************************/
78
79/*!
80@brief Entry in image format table.
81*/
82typedef struct {
83
84 /*!
85 A unique name identifying the format.
86 */
87 const char *name;
88
89 /*!
90 A short description of the format.
91 */
92 const char *desc;
93
94 /*!
95 A whitespace delimited list of file extensions associated with the format.
96 */
97 const char *exts;
98
99 /*!
100 The operations for the format (e.g., encode, decode, and validate).
101 */
102 const jas_image_fmtops_t ops;
103
104 /*!
105 A boolean flag indicating if the format is enabled.
106 */
107 int enabled;
108
109} jas_image_fmt_t;
110
111/*
112User-configurable settings for library.
113This is for internal library use only.
114*/
115typedef struct {
116
117 /*
118 A boolean flag indicating if the library has been configured
119 by invoking the jas_conf_clear function.
120 */
121 bool initialized;
122
123 /*
124 A boolean flag indicating if the library is potentially going to be
125 used by more than one thread.
126 */
127 bool multithread;
128
129 /*
130 The allocator to be used by the library.
131 */
132 jas_allocator_t *allocator;
133
134 /*
135 A boolean flag indicating if the allocator should be accessed through
136 a wrapper that allows memory usage to be tracked and limited.
137 */
138 bool enable_allocator_wrapper;
139
140 /*
141 The maximum amount of memory to be used by the library if the
142 allocator wrapper is used.
143 */
144 size_t max_mem;
145 bool max_mem_valid;
146
147 /*
148 The image format information to be used to populate the image format
149 table in newly created contexts.
150 */
151 const jas_image_fmt_t *image_formats;
152 size_t num_image_formats;
153
154 /*
155 The maximum number of samples allowable in an image to be decoded to be
156 used in newly created contexts.
157 */
158 size_t dec_default_max_samples;
159
160 /*
161 The level of debugging checks/output enabled by the library for newly
162 created contexts.
163 A larger value corresponds to a greater level of debugging checks/output.
164 */
165 int debug_level;
166
167 /*
168 The function used to output error/warning/informational messages
169 for newly created contexts.
170 */
171 int (*vlogmsgf)(jas_logtype_t type, const char *format, va_list ap);
172
173} jas_conf_t;
174
175typedef struct {
176
177 /* A copy of the run-time library configuration settings. */
178 jas_conf_t conf;
179
180 /* A flag indicating if the library is initialized.*/
181 bool initialized;
182
183 /* The number of threads currently using the library. */
184 size_t num_active_threads;
185
186 /*
187 If JAS_THREADS is not defined, this pointer is used for both the
188 global context and default context.
189 Otherwise, this pointer is only used for the global context.
190 */
191 jas_ctx_t *ctx;
192
193 /*
194 The storage for the global context.
195 */
196 jas_ctx_t ctx_buf;
197
198#if defined(JAS_THREADS)
199
200 /* A mutex to protect this data structure. */
201 jas_mutex_t lock;
202
203 /* The TSS for the current context pointer. */
204 jas_tss_t cur_ctx_tss;
205
206 /* The TSS for the default context pointer. */
207 jas_tss_t default_ctx_tss;
208
209#endif
210
211} jas_global_t;
212
213/******************************************************************************\
214* Function prototypes.
215\******************************************************************************/
216
217//static jas_conf_t *jas_get_conf_ptr(void);
218void jas_ctx_init(jas_ctx_t *ctx);
219static int jas_init_codecs(jas_ctx_t *ctx);
220void jas_ctx_cleanup(jas_ctx_t *ctx);
221void jas_set_ctx(jas_ctx_t *ctx);
222void jas_set_default_ctx(jas_ctx_t *ctx);
223jas_ctx_t *jas_ctx_create(void);
224void jas_ctx_destroy(jas_ctx_t *ctx);
225jas_ctx_t *jas_get_ctx_internal(void);
226jas_ctx_t *jas_get_default_ctx(void);
227
228/******************************************************************************\
229* Codec Table.
230\******************************************************************************/
231
232static const jas_image_fmt_t jas_image_fmts[] = {
233
234#if defined(JAS_INCLUDE_PNM_CODEC)
235 {
236 .name = "pnm",
237 .desc = "Portable Graymap/Pixmap (PNM)",
238 .exts = "pnm pbm pgm ppm",
239 .ops = {
240 .decode = pnm_decode,
241 .encode = pnm_encode,
242 .validate = pnm_validate
243 },
244 .enabled = JAS_ENABLE_PNM_CODEC,
245 },
246#endif
247
248#if defined(JAS_INCLUDE_BMP_CODEC)
249 {
250 .name = "bmp",
251 .desc = "Microsoft Bitmap (BMP)",
252 .exts = "bmp",
253 .ops = {
254 .decode = bmp_decode,
255 .encode = bmp_encode,
256 .validate = bmp_validate
257 },
258 .enabled = JAS_ENABLE_BMP_CODEC,
259 },
260#endif
261
262#if defined(JAS_INCLUDE_RAS_CODEC)
263 {
264 .name = "ras",
265 .desc = "Sun Rasterfile (RAS)",
266 .exts = "ras",
267 .ops = {
268 .decode = ras_decode,
269 .encode = ras_encode,
270 .validate = ras_validate
271 },
272 .enabled = JAS_ENABLE_RAS_CODEC,
273 },
274#endif
275
276#if defined(JAS_INCLUDE_PGX_CODEC)
277 {
278 .name = "pgx",
279 .desc = "JPEG-2000 VM Format (PGX)",
280 .exts = "pgx",
281 .ops = {
282 .decode = pgx_decode,
283 .encode = pgx_encode,
284 .validate = pgx_validate
285 },
286 .enabled = JAS_ENABLE_PGX_CODEC,
287 },
288#endif
289
290#if defined(JAS_INCLUDE_JPC_CODEC) || defined(JAS_INCLUDE_JP2_CODEC)
291 {
292 .name = "jpc",
293 .desc = "JPEG-2000 Code Stream Syntax (ISO/IEC 15444-1)",
294 .exts = "jpc",
295 .ops = {
296 .decode = jpc_decode,
297 .encode = jpc_encode,
298 .validate = jpc_validate
299 },
300 .enabled = JAS_ENABLE_JPC_CODEC,
301 },
302#endif
303
304#if defined(JAS_INCLUDE_JP2_CODEC)
305 {
306 .name = "jp2",
307 .desc = "JPEG-2000 JP2 File Format Syntax (ISO/IEC 15444-1)",
308 .exts = "jp2",
309 .ops = {
310 .decode = jp2_decode,
311 .encode = jp2_encode,
312 .validate = jp2_validate
313 },
314 .enabled = JAS_ENABLE_JP2_CODEC,
315 },
316#endif
317
318#if defined(JAS_INCLUDE_MIF_CODEC) && defined(JAS_ENABLE_MIF_CODEC)
319 {
320 .name = "mif",
321 .desc = "My Image Format (MIF)",
322 .exts = "mif",
323 .ops = {
324 .decode = mif_decode,
325 .encode = mif_encode,
326 .validate = mif_validate
327 },
328 .enabled = JAS_ENABLE_MIF_CODEC,
329 },
330#endif
331
332#if defined(JAS_INCLUDE_JPG_CODEC)
333 {
334 .name = "jpg",
335 .desc = "JPEG (ISO/IEC 10918-1)",
336 .exts = "jpg",
337 .ops = {
338 .decode = jpg_decode,
339 .encode = jpg_encode,
340 .validate = jpg_validate
341 },
342 .enabled = JAS_ENABLE_JPG_CODEC,
343 },
344#endif
345
346#if defined(JAS_INCLUDE_HEIC_CODEC)
347 {
348 .name = "heic",
349 .desc = "HEIC (ISO/IEC 23008-12)",
350 .exts = "heic heif",
351 .ops = {
352 .decode = jas_heic_decode,
353 .encode = jas_heic_encode,
354 .validate = jas_heic_validate
355 },
356 .enabled = JAS_ENABLE_HEIC_CODEC,
357 },
358#endif
359
360};
361
362/******************************************************************************\
363* Configuration and Library Data.
364\******************************************************************************/
365
366/* MUTABLE_SHARED_STATE_TAG: This is mutable shared state. */
367/*
368Various user-configurable settings.
369*/
370jas_conf_t jas_conf = {
371 .initialized = 0,
372};
373
374/* MUTABLE_SHARED_STATE_TAG: This is mutable shared state. */
375jas_global_t jas_global = {
376 .initialized = 0,
377#if defined(JAS_THREADS)
378 .lock = JAS_MUTEX_INITIALIZER,
379#endif
380};
381
382#if defined(JAS_HAVE_THREAD_LOCAL)
383_Thread_local jas_ctx_t *jas_cur_ctx = 0;
384_Thread_local jas_ctx_t *jas_default_ctx = 0;
385#endif
386
387/******************************************************************************\
388* Library Configuration.
389\******************************************************************************/
390
391JAS_EXPORT
392void jas_conf_clear()
393{
394 jas_conf.multithread = 0;
395 jas_conf.allocator = 0;
396 jas_conf.enable_allocator_wrapper = 1;
397 jas_conf.max_mem = 0;
398 jas_conf.max_mem_valid = 0;
399 jas_conf.num_image_formats = sizeof(jas_image_fmts) /
400 sizeof(jas_image_fmt_t);
401 jas_conf.image_formats = jas_image_fmts;
402#if defined(JAS_LEGACY_MODE)
403 jas_conf.dec_default_max_samples = JAS_DEC_DEFAULT_MAX_SAMPLES;
404#else
405 jas_conf.dec_default_max_samples = 0;
406#endif
407 jas_conf.debug_level = 0;
408 jas_conf.vlogmsgf = jas_vlogmsgf_stderr;
409 //jas_conf.vlogmsgf = jas_vlogmsgf_discard;
410 jas_conf.initialized = 1;
411}
412
413JAS_EXPORT
414void jas_conf_set_multithread(int multithread)
415{
416 jas_conf.multithread = multithread;
417}
418
419JAS_EXPORT
420void jas_conf_set_allocator(jas_allocator_t *allocator)
421{
422 jas_conf.allocator = allocator;
423}
424
425#ifdef JAS_COMMENT
426JAS_EXPORT
427void jas_conf_set_allocator_wrapper(int enabled)
428{
429 jas_conf.enable_allocator_wrapper = enabled;
430}
431#endif
432
433JAS_EXPORT
434void jas_conf_set_debug_level(int debug_level)
435{
436 jas_conf.debug_level = debug_level;
437}
438
439JAS_EXPORT
440void jas_conf_set_max_mem_usage(size_t max_mem)
441{
442 jas_conf.max_mem = max_mem;
443 jas_conf.max_mem_valid = 1;
444}
445
446JAS_EXPORT
447void jas_conf_set_dec_default_max_samples(size_t n)
448{
449 jas_conf.dec_default_max_samples = n;
450}
451
452JAS_EXPORT
453void jas_conf_set_vlogmsgf(int (*func)(jas_logtype_t type, const char *,
454 va_list))
455{
456 jas_conf.vlogmsgf = func;
457}
458
459/******************************************************************************\
460* Library Initialization and Cleanup.
461\******************************************************************************/
462
463/*
464Note: I think that it should actually be okay for jas_init_library and
465jas_cleanup_library to be called from different threads, since:
466the mutex ensures synchronization and also guarantees that only one
467thread can use the global context at once.
468*/
469JAS_EXPORT
470int jas_init_library()
471{
472 int ret = 0;
473#if defined(JAS_THREADS)
474 bool has_lock = false;
475#endif
476
477#if defined(JAS_THREADS)
478 jas_mutex_lock(&jas_global.lock);
479 has_lock = true;
480#endif
481
482 /*
483 The following check requires that library configuration be performed on
484 the same thread as library initialization.
485 */
486 if (!jas_conf.initialized) {
487 jas_eprintf("FATAL ERROR: "
488 "jas_init_library called before JasPer library configured\n");
489 abort();
490 }
491
492 /*
493 The following check requires that library configuration be performed on
494 the same thread as library initialization.
495 */
496 assert(jas_conf.initialized);
497 assert(!jas_global.initialized);
498
499 jas_global.conf = jas_conf;
500 assert(jas_global.conf.initialized);
501
502 size_t max_mem;
503 size_t total_mem_size = jas_get_total_mem_size();
504 /*
505 NOTE: The values of jas_global.conf.max_mem_valid and max_mem are
506 used later in a deferred warning message. So, their values should be
507 kept for later.
508 */
509 if (!jas_global.conf.max_mem_valid) {
510 max_mem = total_mem_size / 2;
511 if (!max_mem) {
512 max_mem = JAS_DEFAULT_MAX_MEM_USAGE;
513 }
514 assert(max_mem);
515 jas_global.conf.max_mem = max_mem;
516 } else {
517 max_mem = jas_global.conf.max_mem;
518 }
519 if (max_mem > total_mem_size && total_mem_size > 0) {
520 jas_eprintf("WARNING: JasPer memory limit set to EXCESSIVELY "
521 "LARGE value (i.e., limit exceeds system memory size (%lld > %lld)\n",
522 (long long)max_mem, (long long)total_mem_size);
523 }
524
525#if !defined(JAS_THREADS)
526 if (jas_global.conf.multithread) {
527 jas_eprintf("library not built with multithreading support\n");
528 ret = -1;
529 goto done;
530 }
531#endif
532
533#if defined(JAS_THREADS) && !defined(JAS_HAVE_THREAD_LOCAL)
534 memset(&jas_global.cur_ctx_tss, 0, sizeof(jas_tss_t));
535 memset(&jas_global.default_ctx_tss, 0, sizeof(jas_tss_t));
536#endif
537
538 /*
539 The initialization of the global context must be performed first.
540 The memory allocator uses information from the context in order to
541 handle log messages.
542 */
543 jas_ctx_init(&jas_global.ctx_buf);
544 jas_global.ctx = &jas_global.ctx_buf;
545
546 if (jas_global.conf.enable_allocator_wrapper) {
547 jas_allocator_t *delegate;
548 if (!jas_global.conf.allocator) {
549 jas_std_allocator_init(&jas_std_allocator);
550 delegate = &jas_std_allocator.base;
551 } else {
552 delegate = jas_global.conf.allocator;
553 }
554 jas_basic_allocator_init(&jas_basic_allocator, delegate,
555 jas_global.conf.max_mem);
556 jas_allocator = &jas_basic_allocator.base;
557 } else {
558 if (!jas_global.conf.allocator) {
559 jas_std_allocator_init(&jas_std_allocator);
560 jas_allocator = &jas_std_allocator.base;
561 } else {
562 jas_allocator = jas_global.conf.allocator;
563 }
564 }
565
566#if defined(JAS_THREADS) && !defined(JAS_HAVE_THREAD_LOCAL)
567 if ((status = jas_tss_create(&jas_global.cur_ctx_tss, 0))) {
568 jas_eprintf("cannot create thread-specific storage %d\n", status);
569 ret = -1;
570 goto done;
571 }
572 if ((status = jas_tss_create(&jas_global.default_ctx_tss, 0))) {
573 jas_eprintf("cannot create thread-specific storage %d\n", status);
574 ret = -1;
575 goto done;
576 }
577#endif
578
579 jas_global.ctx->dec_default_max_samples =
580 jas_global.conf.dec_default_max_samples;
581 jas_global.ctx->debug_level = jas_global.conf.debug_level;
582 jas_global.ctx->image_numfmts = 0;
583
584 jas_global.initialized = 1;
585
586#if defined(JAS_THREADS)
587 jas_mutex_unlock(&jas_global.lock);
588 has_lock = false;
589#endif
590
591 JAS_LOGDEBUGF(1, "JasPer library version: %s (%d.%d.%d)\n", JAS_VERSION,
592 JAS_VERSION_MAJOR, JAS_VERSION_MINOR, JAS_VERSION_PATCH);
593
594 if (!jas_global.conf.max_mem_valid) {
595 jas_eprintf(
596 "warning: The application program did not set the memory limit "
597 "for the JasPer library.\n"
598 );
599 jas_eprintf(
600 "warning: The JasPer memory limit is being defaulted to a "
601 "value that may be inappropriate for the system. If the default "
602 "is too small, some reasonable encoding/decoding operations will "
603 "fail. If the default is too large, security vulnerabilities "
604 "will result (e.g., decoding a malicious image could exhaust all "
605 "memory and crash the system.\n"
606 );
607 jas_eprintf("warning: setting JasPer memory limit to %lld bytes\n",
608 (long long)max_mem);
609 }
610
611 JAS_LOGDEBUGF(1, "JasPer library initialization complete\n");
612 JAS_LOGDEBUGF(1, "total memory size: %zu\n", jas_get_total_mem_size());
613 JAS_LOGDEBUGF(1, "JasPer library memory limit: %zu\n", max_mem);
614
615#if !defined(JAS_THREADS) || (defined(JAS_THREADS) && !defined(JAS_HAVE_THREAD_LOCAL))
616done:
617#endif
618#if defined(JAS_THREADS)
619 if (has_lock) {
620 jas_mutex_unlock(&jas_global.lock);
621 }
622#endif
623
624 return ret;
625}
626
627JAS_EXPORT
628int jas_cleanup_library()
629{
630 jas_ctx_t *ctx;
631#if defined(JAS_THREADS)
632 bool has_lock = false;
633#endif
634
635#if defined(JAS_THREADS)
636 jas_mutex_lock(&jas_global.lock);
637 has_lock = true;
638#endif
639
640 if (!jas_global.initialized) {
641 jas_eprintf("FATAL ERROR: "
642 "jas_cleanup_library called before JasPer library initialized\n");
643 abort();
644 }
645 if (jas_global.num_active_threads) {
646 jas_eprintf("FATAL ERROR: "
647 "jas_cleanup_library called with active JasPer threads\n");
648 abort();
649 }
650
651 assert(jas_global.initialized);
652 assert(!jas_global.num_active_threads);
653
654 JAS_LOGDEBUGF(10, "jas_cleanup_library invoked\n");
655
656 ctx = &jas_global.ctx_buf;
657 jas_ctx_cleanup(ctx);
658 //jas_context_set_debug_level(ctx, 0);
659
660#if defined(JAS_THREADS) && !defined(JAS_HAVE_THREAD_LOCAL)
661 jas_tss_delete(jas_global.cur_ctx_tss);
662 jas_tss_delete(jas_global.default_ctx_tss);
663#endif
664
665 assert(jas_allocator);
666 jas_allocator_cleanup(jas_allocator);
667 jas_allocator = 0;
668
669 JAS_LOGDEBUGF(10, "jas_cleanup_library returning\n");
670
671 jas_global.initialized = 0;
672 jas_conf.initialized = 0;
673
674#if defined(JAS_THREADS)
675 if (has_lock) {
676 jas_mutex_unlock(&jas_global.lock);
677 }
678#endif
679
680 return 0;
681}
682
683/******************************************************************************\
684* Thread Initialization and Cleanup.
685\******************************************************************************/
686
687JAS_EXPORT
688int jas_init_thread()
689{
690 int ret = 0;
691 jas_ctx_t *ctx;
692#if defined(JAS_THREADS)
693 bool has_lock = false;
694#endif
695
696 /*
697 The default context must be established as soon as possible.
698 Prior to the default context being initialized the global state in
699 jas_global.conf is used for some settings (e.g., debug level
700 and logging function).
701 Due to the use of this global state, we must hold the lock on
702 this state until the default context is initialized.
703 */
704#if defined(JAS_THREADS)
705 jas_mutex_lock(&jas_global.lock);
706 has_lock = true;
707#endif
708
709 if (!jas_global.initialized) {
710 jas_eprintf("FATAL ERROR: "
711 "jas_init_thread called before JasPer library initialized\n");
712 abort();
713 }
714 assert(jas_global.initialized);
715#if !defined(JAS_THREADS)
716 assert(jas_global.num_active_threads == 0);
717#endif
718 assert(jas_get_ctx() == jas_global.ctx);
719 assert(!jas_get_default_ctx() || jas_get_default_ctx() ==
720 &jas_global.ctx_buf);
721
722 if (!(ctx = jas_ctx_create())) {
723 ret = -1;
724 goto done;
725 }
726 jas_set_ctx(ctx);
727 /* As of this point, shared use of jas_global.conf is no longer needed. */
728 jas_set_default_ctx(ctx);
729 ++jas_global.num_active_threads;
730
731#if defined(JAS_THREADS)
732 jas_mutex_unlock(&jas_global.lock);
733 has_lock = false;
734#endif
735
736done:
737#if defined(JAS_THREADS)
738 if (has_lock) {
739 jas_mutex_unlock(&jas_global.lock);
740 }
741#endif
742 if (ret && ctx) {
743 jas_ctx_cleanup(ctx);
744 }
745 return ret;
746}
747
748JAS_EXPORT
749int jas_cleanup_thread()
750{
751 jas_ctx_t *ctx;
752#if defined(JAS_THREADS)
753 bool has_lock = false;
754#endif
755
756#if defined(JAS_THREADS)
757 jas_mutex_lock(&jas_global.lock);
758 has_lock = true;
759#endif
760
761 if (!jas_get_default_ctx()) {
762 jas_eprintf("FATAL ERROR: "
763 "jas_cleanup_thread called before JasPer thread initialized\n");
764 abort();
765 }
766
767 assert(jas_get_default_ctx());
768 assert(jas_get_ctx());
769
770 /* Ensure that the library user is not doing something insane. */
771 assert(jas_get_ctx() == jas_get_default_ctx());
772
773 ctx = jas_get_default_ctx();
774 jas_set_default_ctx(0);
775 jas_set_ctx(0);
776 /*
777 As soon as we clear the current context, the global shared state
778 jas_conf.conf is used for various settings (e.g., debug level and
779 logging function).
780 */
781
782 jas_ctx_destroy(ctx);
783 --jas_global.num_active_threads;
784
785#if defined(JAS_THREADS)
786 if (has_lock) {
787 jas_mutex_unlock(&jas_global.lock);
788 }
789#endif
790
791 return 0;
792}
793
794/******************************************************************************\
795* Legacy Library Initialization and Cleanup.
796\******************************************************************************/
797
798JAS_EXPORT
799int jas_init()
800{
801 jas_deprecated("use of jas_init is deprecated\n");
802 jas_conf_clear();
803 if (jas_init_library()) {
804 return -1;
805 }
806 if (jas_init_thread()) {
807 jas_cleanup_library();
808 return -1;
809 }
810 return 0;
811}
812
813JAS_EXPORT
814void jas_cleanup()
815{
816 jas_deprecated("use of jas_cleanup is deprecated\n");
817 if (jas_cleanup_thread()) {
818 jas_eprintf("jas_cleanup_thread failed\n");
819 }
820 if (jas_cleanup_library()) {
821 jas_eprintf("jas_cleanup_library failed\n");
822 }
823}
68 824
69/******************************************************************************\825/******************************************************************************\
70* Code.826* Code.
71\******************************************************************************/827\******************************************************************************/
72 828
73/* Initialize the image format table. */829/* Initialize the image format table. */
74JAS_DLLEXPORT830static int jas_init_codecs(jas_ctx_t *ctx)
75int jas_init(void)
76{831{
77 jas_image_fmtops_t fmtops;832 int ret = 0;
78 int fmtid = 0;833 int i;
834 const jas_image_fmt_t *fmt;
835 for (fmt = jas_global.conf.image_formats, i = 0;
836 i < jas_global.conf.num_image_formats; ++fmt, ++i) {
837 JAS_LOGDEBUGF(10, "adding image format %s %s\n", fmt->name, fmt->exts);
838 if (jas_image_addfmt_internal(ctx->image_fmtinfos, &ctx->image_numfmts,
839 i, fmt->name, fmt->exts, fmt->desc, &fmt->ops)) {
840 ret = -1;
841 break;
842 }
843 assert(ctx->image_fmtinfos[i].id == i);
844 ctx->image_fmtinfos[i].enabled = fmt->enabled;
845 }
846 if (ret) {
847 jas_image_clearfmts_internal(ctx->image_fmtinfos, &ctx->image_numfmts);
848 }
849 return ret;
850}
79 851
80#if defined(JAS_INCLUDE_JP2_CODEC)852/******************************************************************************\
81 fmtops.decode = jp2_decode;853* Context management (e.g., creation and destruction).
82 fmtops.validate = jp2_validate;854\******************************************************************************/
83 jas_image_addfmt(fmtid++, "jp2", "jp2",855
84 "JPEG-2000 JP2 File Format Syntax (ISO/IEC 15444-1)", &fmtops);856void jas_ctx_init(jas_ctx_t *ctx)
857{
858 ctx->dec_default_max_samples = jas_conf.dec_default_max_samples;
859 ctx->debug_level = jas_conf.debug_level;
860 ctx->vlogmsgf = jas_conf.vlogmsgf;
861 ctx->image_numfmts = 0;
862 memset(ctx->image_fmtinfos, 0, sizeof(ctx->image_fmtinfos));
863}
864
865jas_ctx_t *jas_ctx_create()
866{
867 jas_ctx_t *ctx;
868 if (!(ctx = jas_malloc(sizeof(jas_ctx_t)))) {
869 return 0;
870 }
871 jas_ctx_init(ctx);
872 jas_init_codecs(ctx);
873 return ctx;
874}
875
876JAS_EXPORT
877jas_context_t jas_context_create()
878{
879 return JAS_CAST(jas_context_t, jas_ctx_create());
880}
881
882void jas_ctx_cleanup(jas_ctx_t *ctx)
883{
884 jas_image_clearfmts_internal(ctx->image_fmtinfos, &ctx->image_numfmts);
885}
886
887void jas_ctx_destroy(jas_ctx_t *ctx)
888{
889 jas_ctx_cleanup(ctx);
890 jas_free(ctx);
891}
892
893JAS_EXPORT
894void jas_context_destroy(jas_context_t context)
895{
896 jas_ctx_destroy(JAS_CAST(jas_ctx_t *, context));
897}
898
899jas_ctx_t *jas_get_ctx_internal()
900{
901#if defined(JAS_THREADS)
902 jas_ctx_t *ctx;
903#if defined(JAS_HAVE_THREAD_LOCAL)
904 ctx = JAS_CAST(jas_ctx_t *, jas_cur_ctx);
905#else
906 ctx = JAS_CAST(jas_ctx_t *, jas_tss_get(jas_global.cur_ctx_tss));
85#endif907#endif
908 if (!ctx) {
909 ctx = jas_global.ctx;
910 }
911 assert(ctx);
912 return ctx;
913#else
914 return (jas_global.ctx) ? jas_global.ctx : &jas_global.ctx_buf;
915#endif
916}
86 917
87#if defined(JAS_INCLUDE_JPC_CODEC) || defined(JAS_INCLUDE_JP2_CODEC)918JAS_EXPORT
88 fmtops.decode = jpc_decode;919jas_context_t jas_get_context()
89 fmtops.validate = jpc_validate;920{
90 jas_image_addfmt(fmtid, "jpc", "jpc",921 return JAS_CAST(jas_context_t, jas_get_ctx());
91 "JPEG-2000 Code Stream Syntax (ISO/IEC 15444-1)", &fmtops);922}
923
924JAS_EXPORT
925jas_context_t jas_get_default_context()
926{
927 return JAS_CAST(jas_context_t, jas_get_default_ctx());
928}
929
930JAS_EXPORT
931void jas_set_context(jas_context_t context)
932{
933 jas_set_ctx(JAS_CAST(jas_ctx_t *, context));
934}
935
936void jas_set_ctx(jas_ctx_t *ctx)
937{
938#if defined(JAS_THREADS)
939#if defined(JAS_HAVE_THREAD_LOCAL)
940 jas_cur_ctx = ctx;
941#else
942 if (jas_tss_set(jas_global.cur_ctx_tss, ctx)) {
943 assert(0);
944 abort();
945 }
946#endif
947#else
948 jas_global.ctx = JAS_CAST(jas_ctx_t *, ctx);
92#endif949#endif
950}
93 951
94 /* We must not register the JasPer library exit handler until after952jas_ctx_t *jas_get_default_ctx()
95 at least one memory allocation is performed. This is desirable953{
96 as it ensures that the JasPer exit handler is called before the954 jas_ctx_t *ctx;
97 debug memory allocator exit handler. */
98 atexit(jas_cleanup);
99 955
100 return 0;956#if defined(JAS_THREADS)
957# if defined(JAS_HAVE_THREAD_LOCAL)
958 ctx = jas_default_ctx;
959# else
960 ctx = JAS_CAST(jas_ctx_t *, jas_tss_get(jas_global.default_ctx_tss));
961# endif
962 if (!ctx) {
963 ctx = jas_global.ctx;
964 }
965#else
966 ctx = (jas_global.ctx) ? jas_global.ctx : &jas_global.ctx_buf;
967#endif
968 //JAS_LOGDEBUGF(100, "jas_get_ctx() returning %p", JAS_CAST(void *, ctx));
969
970 return ctx;
971}
972
973void jas_set_default_ctx(jas_ctx_t *ctx)
974{
975#if defined(JAS_THREADS)
976#if defined(JAS_HAVE_THREAD_LOCAL)
977 jas_default_ctx = ctx;
978#else
979 if (jas_tss_set(jas_global.default_ctx_tss, ctx)) {
980 assert(0);
981 abort();
982 }
983#endif
984#else
985 jas_global.ctx = JAS_CAST(jas_ctx_t *, ctx);
986#endif
987}
988
989/******************************************************************************\
990* Context state management.
991\******************************************************************************/
992
993JAS_EXPORT
994void jas_set_debug_level(int debug_level)
995{
996 jas_ctx_t *ctx = jas_get_ctx();
997 ctx->debug_level = debug_level;
998}
999
1000JAS_EXPORT
1001int jas_get_debug_level_internal(void)
1002{
1003 jas_ctx_t *ctx = jas_get_ctx();
1004 return ctx->debug_level;
1005}
1006
1007JAS_EXPORT
1008void jas_set_dec_default_max_samples(size_t max_samples)
1009{
1010 jas_ctx_t *ctx = jas_get_ctx();
1011 ctx->dec_default_max_samples = max_samples;
1012}
1013
1014JAS_EXPORT
1015size_t jas_get_dec_default_max_samples_internal(void)
1016{
1017 jas_ctx_t *ctx = jas_get_ctx();
1018 return ctx->dec_default_max_samples;
1019}
1020
1021JAS_EXPORT
1022void jas_set_vlogmsgf(int (*func)(jas_logtype_t, const char *, va_list))
1023{
1024 jas_ctx_t *ctx = jas_get_ctx();
1025 ctx->vlogmsgf = func;
101}1026}
102 1027
103JAS_DLLEXPORT1028JAS_EXPORT
104void jas_cleanup(void)1029jas_vlogmsgf_t *jas_get_vlogmsgf_internal(void)
105{1030{
106 jas_image_clearfmts();1031 jas_ctx_t *ctx = jas_get_ctx();
1032 return ctx->vlogmsgf;
107}1033}
jas_malloc.c+651−0
@@ -0,0 +1,651 @@
1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2002 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64/*
65 * Memory Allocator
66 *
67 * $Id$
68 */
69
70/******************************************************************************\
71* Includes.
72\******************************************************************************/
73
74#define JAS_FOR_INTERNAL_USE_ONLY
75
76#include "jasper/jas_types.h"
77#include "jasper/jas_malloc.h"
78#include "jasper/jas_debug.h"
79#include "jasper/jas_math.h"
80
81#if defined(__linux__)
82# include <sys/sysinfo.h>
83#elif defined(__APPLE__)
84# include <sys/types.h>
85# include <sys/sysctl.h>
86#elif defined(__unix__) && (!defined(__linux__) && !defined(__APPLE__))
87# include <unistd.h>
88#elif defined(_WIN32)
89# include <windows.h>
90# include <sysinfoapi.h>
91#endif
92
93/******************************************************************************\
94* Data.
95\******************************************************************************/
96
97/* MUTABLE_SHARED_STATE_TAG: This is mutable shared state. */
98/* The memory allocator object to be used for all memory allocation. */
99jas_allocator_t *jas_allocator = 0;
100
101/* MUTABLE_SHARED_STATE_TAG: This is mutable shared state. */
102jas_std_allocator_t jas_std_allocator = {
103 .base = {
104 .cleanup = 0,
105 .alloc = 0,
106 .free = 0,
107 .realloc = 0,
108 },
109};
110
111/* MUTABLE_SHARED_STATE_TAG: This is mutable shared state. */
112jas_basic_allocator_t jas_basic_allocator = {
113 .base = {
114 .cleanup = 0,
115 .alloc = 0,
116 .free = 0,
117 .realloc = 0,
118 },
119 .delegate = 0,
120 .mem = 0,
121 .max_mem = 0,
122};
123
124/******************************************************************************\
125* Basic memory allocation and deallocation primitives.
126\******************************************************************************/
127
128JAS_EXPORT
129void *jas_malloc(size_t size)
130{
131 assert(jas_allocator);
132 void *result;
133 JAS_LOGDEBUGF(101, "jas_malloc(%zu)\n", size);
134#if defined(JAS_MALLOC_RETURN_NULL_PTR_FOR_ZERO_SIZE)
135 result = size ? (jas_allocator->alloc)(jas_allocator, size) : 0;
136#else
137 result = (jas_allocator->alloc)(jas_allocator, size ? size : 1);
138#endif
139 JAS_LOGDEBUGF(100, "jas_malloc(%zu) -> %p\n", size, result);
140 return result;
141}
142
143JAS_EXPORT
144void *jas_realloc(void *ptr, size_t size)
145{
146 assert(jas_allocator);
147 void *result;
148 JAS_LOGDEBUGF(101, "jas_realloc(%p, %zu)\n", ptr, size);
149 if (!size) {
150 jas_logwarnf("warning: zero size reallocations are unwise "
151 "(and have undefined behavior as of C23)\n");
152 }
153 if (!ptr) {
154 if (size) {
155 /* Handle a new allocation of nonzero size. */
156 result = (jas_allocator->alloc)(jas_allocator, size);
157 JAS_LOGDEBUGF(101, "jas_realloc: alloc(%p, %zu) -> %p\n",
158 jas_allocator, size, result);
159 } else {
160 /* Handle a new allocation of zero size. */
161#if defined(JAS_MALLOC_RETURN_NULL_PTR_FOR_ZERO_SIZE)
162 result = 0;
163 JAS_LOGDEBUGF(101, "jas_realloc: no-op -> %p\n", result);
164#else
165 result = (jas_allocator->alloc)(jas_allocator, 1);
166 JAS_LOGDEBUGF(101, "jas_realloc: alloc(%p, %p, %zu) -> %p\n",
167 jas_allocator, ptr, size, result);
168#endif
169 }
170 } else {
171 result = (jas_allocator->realloc)(jas_allocator, ptr, size);
172 JAS_LOGDEBUGF(100, "jas_realloc: realloc(%p, %p, %zu) -> %p\n",
173 jas_allocator, ptr, size, result);
174 }
175 return result;
176}
177
178JAS_EXPORT
179void jas_free(void *ptr)
180{
181 assert(jas_allocator);
182 JAS_LOGDEBUGF(100, "jas_free(%p)\n", ptr);
183 (jas_allocator->free)(jas_allocator, ptr);
184}
185
186/******************************************************************************\
187* Additional memory allocation and deallocation primitives
188* (mainly for overflow checking).
189\******************************************************************************/
190
191void *jas_calloc(size_t num_elements, size_t element_size)
192{
193 void *ptr;
194 size_t size;
195 if (!jas_safe_size_mul(num_elements, element_size, &size)) {
196 return 0;
197 }
198 if (!(ptr = jas_malloc(size))) {
199 return 0;
200 }
201 memset(ptr, 0, size);
202 return ptr;
203}
204
205void *jas_alloc2(size_t num_elements, size_t element_size)
206{
207 size_t size;
208 if (!jas_safe_size_mul(num_elements, element_size, &size)) {
209 return 0;
210 }
211 return jas_malloc(size);
212}
213
214void *jas_alloc3(size_t num_arrays, size_t array_size, size_t element_size)
215{
216 size_t size;
217 if (!jas_safe_size_mul(array_size, element_size, &size) ||
218 !jas_safe_size_mul(size, num_arrays, &size)) {
219 return 0;
220 }
221 return jas_malloc(size);
222}
223
224void *jas_realloc2(void *ptr, size_t num_elements, size_t element_size)
225{
226 size_t size;
227 if (!jas_safe_size_mul(num_elements, element_size, &size)) {
228 return 0;
229 }
230 return jas_realloc(ptr, size);
231}
232
233/******************************************************************************\
234\******************************************************************************/
235
236JAS_EXPORT
237void jas_allocator_cleanup(jas_allocator_t *allocator)
238{
239 if (allocator->cleanup) {
240 (allocator->cleanup)(allocator);
241 }
242}
243
244/******************************************************************************\
245\******************************************************************************/
246
247JAS_EXPORT
248void *jas_std_alloc(jas_allocator_t *allocator, size_t size);
249JAS_EXPORT
250void *jas_std_realloc(jas_allocator_t *allocator, void *ptr, size_t size);
251JAS_EXPORT
252void jas_std_free(jas_allocator_t *allocator, void *ptr);
253
254JAS_EXPORT
255void jas_std_allocator_init(jas_std_allocator_t *allocator)
256{
257 JAS_CAST(void, allocator);
258 allocator->base.cleanup = 0;
259 allocator->base.alloc = jas_std_alloc;
260 allocator->base.free = jas_std_free;
261 allocator->base.realloc = jas_std_realloc;
262}
263
264JAS_EXPORT
265void *jas_std_alloc(jas_allocator_t *allocator, size_t size)
266{
267 JAS_UNUSED(allocator);
268 JAS_LOGDEBUGF(111, "jas_std_alloc(%zu)\n", size);
269 void* result = malloc(size);
270 JAS_LOGDEBUGF(110, "jas_std_alloc(%zu) -> %p\n", size, result);
271 return result;
272}
273
274JAS_EXPORT
275void *jas_std_realloc(jas_allocator_t *allocator, void *ptr, size_t size)
276{
277 JAS_UNUSED(allocator);
278 JAS_LOGDEBUGF(111, "jas_std_realloc(%p, %zu)\n", allocator, size);
279 void *result = realloc(ptr, size);
280 JAS_LOGDEBUGF(110, "jas_std_realloc(%zu) -> %p\n", size, result);
281 return result;
282}
283
284JAS_EXPORT
285void jas_std_free(jas_allocator_t *allocator, void *ptr)
286{
287 JAS_UNUSED(allocator);
288 JAS_LOGDEBUGF(111, "jas_std_free(%p, %p)\n", allocator, ptr);
289 free(ptr);
290}
291
292/******************************************************************************\
293\******************************************************************************/
294
295JAS_EXPORT
296void *jas_basic_alloc(jas_allocator_t *allocator, size_t size);
297JAS_EXPORT
298void *jas_basic_realloc(jas_allocator_t *allocator, void *ptr, size_t size);
299JAS_EXPORT
300void jas_basic_free(jas_allocator_t *allocator, void *ptr);
301JAS_EXPORT
302void jas_basic_cleanup(jas_allocator_t *allocator);
303
304#define JAS_BMA_MAGIC 0xdeadbeefULL
305
306typedef struct {
307 unsigned long long magic;
308 size_t size;
309} jas_mb_t;
310
311#define JAS_MB_ADJUST \
312 ((sizeof(jas_mb_t) + sizeof(max_align_t) - 1) / sizeof(max_align_t))
313#define JAS_MB_SIZE (JAS_MB_ADJUST * sizeof(max_align_t))
314
315static void jas_mb_init(jas_mb_t *mb, size_t size)
316{
317 mb->magic = JAS_BMA_MAGIC;
318 mb->size = size;
319}
320
321static void jas_mb_destroy(jas_mb_t *mb)
322{
323 mb->magic = 0;
324 mb->size = 0;
325}
326
327static void *jas_mb_get_data(jas_mb_t *mb)
328{
329 assert(mb->magic == JAS_BMA_MAGIC);
330 return JAS_CAST(void *, JAS_CAST(max_align_t *, mb) + JAS_MB_ADJUST);
331}
332
333static jas_mb_t *jas_get_mb(void *ptr)
334{
335 assert(ptr);
336 jas_mb_t *mb = JAS_CAST(jas_mb_t *,
337 JAS_CAST(max_align_t *, ptr) - JAS_MB_ADJUST);
338 assert(mb->magic == JAS_BMA_MAGIC);
339 /* This is one check that I do not want disabled with NDEBUG. */
340 if (mb->magic != JAS_BMA_MAGIC) {
341 /* This line of code should never be reached. */
342 assert(0);
343 abort();
344 }
345 return mb;
346}
347
348void jas_set_max_mem_usage(size_t max_mem)
349{
350 assert(jas_allocator == JAS_CAST(jas_allocator_t*, &jas_basic_allocator));
351 jas_basic_allocator_t *allocator = JAS_CAST(jas_basic_allocator_t *,
352 jas_allocator);
353#if defined(JAS_THREADS)
354 jas_mutex_lock(&allocator->mutex);
355#endif
356 allocator->max_mem = (!max_mem || allocator->mem <= max_mem) ? max_mem :
357 allocator->mem;
358#if defined(JAS_THREADS)
359 jas_mutex_unlock(&allocator->mutex);
360#endif
361}
362
363size_t jas_get_mem_usage()
364{
365 assert(jas_allocator == JAS_CAST(jas_allocator_t*, &jas_basic_allocator));
366 jas_basic_allocator_t *allocator = JAS_CAST(jas_basic_allocator_t *,
367 jas_allocator);
368#if defined(JAS_THREADS)
369 jas_mutex_lock(&allocator->mutex);
370#endif
371 size_t result = allocator->mem;
372#if defined(JAS_THREADS)
373 jas_mutex_unlock(&allocator->mutex);
374#endif
375 return result;
376}
377
378void jas_basic_allocator_init(jas_basic_allocator_t *allocator,
379 jas_allocator_t *delegate, size_t max_mem)
380{
381 allocator->base.cleanup = jas_basic_cleanup;
382 allocator->base.alloc = jas_basic_alloc;
383 allocator->base.free = jas_basic_free;
384 allocator->base.realloc = jas_basic_realloc;
385 allocator->delegate = delegate;
386 assert(allocator->base.cleanup != delegate->cleanup);
387 assert(allocator->base.alloc != delegate->alloc);
388 assert(allocator->base.free != delegate->free);
389 assert(allocator->base.realloc != delegate->realloc);
390 allocator->max_mem = max_mem;
391 allocator->mem = 0;
392#if defined(JAS_THREADS)
393 if (jas_mutex_init(&allocator->mutex)) {
394 /* This line of code should never be reached. */
395 assert(0);
396 abort();
397 }
398#endif
399}
400
401JAS_EXPORT
402void jas_basic_cleanup(jas_allocator_t *allocator)
403{
404 jas_basic_allocator_t *a = JAS_CAST(jas_basic_allocator_t *,
405 allocator);
406 if (a->delegate->cleanup) {
407 (a->delegate->cleanup)(allocator);
408 }
409#if defined(JAS_THREADS)
410 jas_mutex_cleanup(&a->mutex);
411#endif
412}
413
414JAS_EXPORT
415void *jas_basic_alloc(jas_allocator_t *allocator, size_t size)
416{
417 void *result;
418 jas_mb_t *mb;
419 size_t ext_size;
420 size_t mem;
421 jas_basic_allocator_t *a = JAS_CAST(jas_basic_allocator_t *, allocator);
422
423 JAS_LOGDEBUGF(100, "jas_basic_alloc(%p, %zu)\n", allocator, size);
424 JAS_LOGDEBUGF(102, "max_mem=%zu; mem=%zu\n", a->max_mem, a->mem);
425#if defined(JAS_MALLOC_RETURN_NULL_PTR_FOR_ZERO_SIZE)
426 if (!size) {
427 result = 0;
428 goto done;
429 }
430#endif
431 if (!jas_safe_size_add(size, JAS_MB_SIZE, &ext_size)) {
432 jas_logerrorf("requested memory size is too large (%zu)\n", size);
433 result = 0;
434 goto done;
435 }
436
437#if defined(JAS_THREADS)
438 jas_mutex_lock(&a->mutex);
439 has_lock = true;
440#endif
441
442 /*
443 Calculate the amount of memory that would be allocated after the requested
444 allocation is performed, being careful to ensure that this computation
445 does not cause overflow. Then, ensure that the computed value does not
446 exceed the memory usage limit.
447 */
448 if (!jas_safe_size_add(a->mem, ext_size, &mem) || mem > a->max_mem) {
449 jas_logerrorf("maximum memory limit (%lld) would be exceeded\n",
450 (long long)a->max_mem);
451 result = 0;
452 goto done;
453 }
454
455 /*
456 Perform the requested allocation using the delegated-to allocator.
457 */
458 JAS_LOGDEBUGF(100, "jas_basic_alloc: alloc(%p, %zu)\n", a->delegate,
459 ext_size);
460 if ((mb = (a->delegate->alloc)(a->delegate, ext_size))) {
461 jas_mb_init(mb, ext_size);
462 result = jas_mb_get_data(mb);
463 a->mem = mem;
464 } else {
465 result = 0;
466 }
467
468done:
469#if defined(JAS_THREADS)
470 if (has_lock) {
471 jas_mutex_unlock(&a->mutex);
472 }
473#endif
474
475 JAS_LOGDEBUGF(99, "jas_basic_alloc(%p, %zu) -> %p (mb=%p)\n", allocator,
476 size, result, mb);
477 JAS_LOGDEBUGF(102, "max_mem=%zu; mem=%zu\n", a->max_mem, a->mem);
478
479 return result;
480}
481
482JAS_EXPORT
483void *jas_basic_realloc(jas_allocator_t *allocator, void *ptr, size_t size)
484{
485 void *result;
486 jas_mb_t *old_mb;
487 size_t old_ext_size;
488 jas_mb_t *mb;
489 size_t ext_size;
490 size_t mem;
491 jas_basic_allocator_t *a = JAS_CAST(jas_basic_allocator_t *, allocator);
492
493 JAS_LOGDEBUGF(100, "jas_basic_realloc(%p, %p, %zu)\n", allocator, ptr,
494 size);
495 /*
496 Check for a realloc operation that is equivalent to an alloc operation.
497 */
498 if (!ptr) {
499 result = jas_basic_alloc(allocator, size);
500 goto done;
501 }
502 /*
503 Check for a realloc operation that is equivalent to a zero-sized
504 allocation/reallocation.
505 */
506 if (ptr && !size) {
507#if defined(JAS_MALLOC_RETURN_NULL_PTR_FOR_ZERO_SIZE)
508 jas_basic_free(allocator, ptr);
509 result = 0;
510#else
511 if ((result = jas_basic_alloc(allocator, 1))) {
512 jas_basic_free(allocator, ptr);
513 }
514#endif
515 goto done;
516 }
517
518 if (!jas_safe_size_add(size, JAS_MB_SIZE, &ext_size)) {
519 jas_logerrorf("requested memory size is too large (%zu)\n", size);
520 result = 0;
521 goto done;
522 }
523
524#if defined(JAS_THREADS)
525 jas_mutex_lock(&a->mutex);
526 has_lock = true;
527#endif
528
529 old_mb = jas_get_mb(ptr);
530 old_ext_size = old_mb->size;
531 JAS_LOGDEBUGF(101, "jas_basic_realloc: old_mb=%p; old_ext_size=%zu\n",
532 old_mb, old_ext_size);
533 /*
534 Skip performing any allocation if the currently-allocated block is
535 sufficiently large to accommodate the allocation request.
536 */
537 if (ext_size <= old_ext_size) {
538 result = jas_mb_get_data(old_mb);
539 goto done;
540 }
541
542 if (!jas_safe_size_add(a->mem, ext_size - old_ext_size, &mem) ||
543 mem > a->max_mem) {
544 jas_logerrorf("maximum memory limit (%zu) would be exceeded\n",
545 a->max_mem);
546 result = 0;
547 goto done;
548 }
549
550 JAS_LOGDEBUGF(100, "jas_basic_realloc: realloc(%p, %p, %zu)\n",
551 a->delegate, old_mb, ext_size);
552 jas_mb_destroy(old_mb);
553 if ((mb = (a->delegate->realloc)(a->delegate, old_mb, ext_size))) {
554 jas_mb_init(mb, ext_size);
555 result = jas_mb_get_data(mb);
556 a->mem = mem;
557 } else {
558 jas_mb_init(old_mb, old_ext_size);
559 result = 0;
560 }
561
562done:
563#if defined(JAS_THREADS)
564 if (has_lock) {
565 jas_mutex_unlock(&a->mutex);
566 }
567#endif
568
569 JAS_LOGDEBUGF(100, "jas_basic_realloc(%p, %p, %zu) -> %p (%p)\n", allocator,
570 ptr, size, result, mb);
571 JAS_LOGDEBUGF(102, "max_mem=%zu; mem=%zu\n", a->max_mem, a->mem);
572
573 return result;
574}
575
576JAS_EXPORT
577void jas_basic_free(jas_allocator_t *allocator, void *ptr)
578{
579 jas_mb_t *mb;
580 size_t ext_size;
581 jas_basic_allocator_t *a = JAS_CAST(jas_basic_allocator_t *, allocator);
582
583
584 JAS_LOGDEBUGF(100, "jas_basic_free(%p)\n", ptr);
585 if (ptr) {
586#if defined(JAS_THREADS)
587 jas_mutex_lock(&a->mutex);
588#endif
589 mb = jas_get_mb(ptr);
590 ext_size = mb->size;
591 JAS_LOGDEBUGF(101, "jas_basic_free(%p, %p) (mb=%p; ext_size=%zu)\n",
592 allocator, ptr, mb, ext_size);
593 if (!jas_safe_size_sub(a->mem, ext_size, &a->mem)) {
594 jas_logerrorf("heap corruption detected (%zu exceeds %zu)\n",
595 ext_size, a->mem);
596 /* This line of code should never be reached. */
597 assert(0);
598 abort();
599 }
600 JAS_LOGDEBUGF(100, "jas_basic_free: free(%p, %p)\n", a->delegate, mb);
601 jas_mb_destroy(mb);
602 (a->delegate->free)(a->delegate, mb);
603#if defined(JAS_THREADS)
604 jas_mutex_unlock(&a->mutex);
605#endif
606 }
607 JAS_LOGDEBUGF(102, "max_mem=%zu; mem=%zu\n", a->max_mem, a->mem);
608
609}
610
611/******************************************************************************\
612\******************************************************************************/
613
614size_t jas_get_total_mem_size()
615{
616#if defined(__linux__)
617 struct sysinfo buf;
618 if (sysinfo(&buf)) {
619 return 0;
620 }
621 return buf.totalram * buf.mem_unit;
622#elif defined(__APPLE__)
623 int mib[] = {CTL_HW, HW_MEMSIZE};
624 uint64_t value = 0;
625 size_t length = sizeof(value);
626 if (sysctl(mib, 2, &value, &length, 0, 0)) {
627 return 0;
628 }
629 return JAS_CAST(size_t, value);
630#elif defined(__unix__) && (!defined(__linux__) && !defined(__APPLE__))
631 /*
632 Reference:
633 https://stackoverflow.com/questions/2513505/how-to-get-available-memory-c-g
634 */
635 long pages = sysconf(_SC_PHYS_PAGES);
636 long page_size = sysconf(_SC_PAGE_SIZE);
637 return pages * page_size;
638#elif defined(_WIN32)
639 /*
640 Reference:
641 https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getphysicallyinstalledsystemmemory
642 */
643 ULONGLONG size;
644 if (!GetPhysicallyInstalledSystemMemory(&size)) {
645 return 0;
646 }
647 return 1024 * size;
648#else
649 return 0;
650#endif
651}
jas_seq.c+9−7
@@ -71,9 +71,12 @@ · 70 unmodified lines
71* Includes.71* Includes.
72\******************************************************************************/72\******************************************************************************/
73 73
74#define JAS_FOR_INTERNAL_USE_ONLY
75
74#include "jasper/jas_seq.h"76#include "jasper/jas_seq.h"
75#include "jasper/jas_malloc.h"77#include "jasper/jas_malloc.h"
76#include "jasper/jas_math.h"78#include "jasper/jas_math.h"
79#include "jasper/jas_debug.h"
77 80
78/******************************************************************************\81/******************************************************************************\
79* Constructors and destructors.82* Constructors and destructors.
@@ -100,6 +103,7 @@ jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols) · 20 unmodified lines
100 jas_matind_t i;103 jas_matind_t i;
101 size_t size;104 size_t size;
102 105
106
103 if (numrows < 0 || numcols < 0) {107 if (numrows < 0 || numcols < 0) {
104 return NULL;108 return NULL;
105 }109 }
@@ -132,9 +136,7 @@ jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols) · 26 unmodified lines
132 sizeof(jas_seqent_t)))) {136 sizeof(jas_seqent_t)))) {
133 goto error;137 goto error;
134 }138 }
135 139 memset(matrix->data_, 0, matrix->datasize_ * sizeof(jas_seqent_t));
136 memset(matrix->data_, 0,
137 matrix->datasize_ * sizeof(jas_seqent_t));
138 }140 }
139 141
140 for (i = 0; i < numrows; ++i) {142 for (i = 0; i < numrows; ++i) {
@@ -201,11 +203,11 @@ int jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, jas_matind_t xstart, · 60 unmodified lines
201 jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend)203 jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend)
202{204{
203 if (xstart < s1->xstart_ || ystart < s1->ystart_ ||205 if (xstart < s1->xstart_ || ystart < s1->ystart_ ||
204 xend > s1->xend_ || yend > s1->yend_)206 xend > s1->xend_ || yend > s1->yend_) {
205 return -1;207 return -1;
206 208 }
207 return jas_matrix_bindsub(s, s1, ystart - s1->ystart_, xstart - s1->xstart_,209 return jas_matrix_bindsub(s, s1, ystart - s1->ystart_,
208 yend - s1->ystart_ - 1, xend - s1->xstart_ - 1);210 xstart - s1->xstart_, yend - s1->ystart_ - 1, xend - s1->xstart_ - 1);
209}211}
210 212
211int jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1,213int jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1,
jas_stream.c+413−157
@@ -71,12 +71,31 @@ · 70 unmodified lines
71* Includes.71* Includes.
72\******************************************************************************/72\******************************************************************************/
73 73
74#include "jasper/jas_config.h"
75
76/* The following must come before any direct/indirect inclusion of stdlib.h. */
77#if defined(JAS_HAVE_MKOSTEMP)
78#define _GNU_SOURCE
79#endif
80
81#define JAS_FOR_INTERNAL_USE_ONLY
82
74#include "jasper/jas_stream.h"83#include "jasper/jas_stream.h"
75#include "jasper/jas_debug.h"84#include "jasper/jas_debug.h"
76#include "jasper/jas_types.h"85#include "jasper/jas_types.h"
77#include "jasper/jas_malloc.h"86#include "jasper/jas_malloc.h"
78#include "jasper/jas_math.h"87#include "jasper/jas_math.h"
79 88
89/*
90O_CLOEXEC is a Linux-specific flag which helps avoid leaking file descriptors
91to child processes created by another thread; for simplicity, we always
92specify it, and this definition is a fallback for systems where this feature
93is not available
94*/
95#ifndef O_CLOEXEC
96#define O_CLOEXEC 0
97#endif
98
80/******************************************************************************\99/******************************************************************************\
81* Local function prototypes.100* Local function prototypes.
82\******************************************************************************/101\******************************************************************************/
@@ -87,13 +106,21 @@ static jas_stream_t *jas_stream_create(void); · 4 unmodified lines
87static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf,106static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf,
88 int bufsize);107 int bufsize);
89 108
90static int mem_read(jas_stream_obj_t *obj, char *buf, unsigned cnt);109static ssize_t mem_read(jas_stream_obj_t *obj, char *buf, size_t cnt);
91static int mem_write(jas_stream_obj_t *obj, const char *buf, unsigned cnt);110static ssize_t mem_write(jas_stream_obj_t *obj, const char *buf,
111 size_t cnt);
92static long mem_seek(jas_stream_obj_t *obj, long offset, int origin);112static long mem_seek(jas_stream_obj_t *obj, long offset, int origin);
93static int mem_close(jas_stream_obj_t *obj);113static int mem_close(jas_stream_obj_t *obj);
94 114
95static int file_read(jas_stream_obj_t *obj, char *buf, unsigned cnt);115static ssize_t sfile_read(jas_stream_obj_t *obj, char *buf, size_t cnt);
96static int file_write(jas_stream_obj_t *obj, const char *buf, unsigned cnt);116static ssize_t sfile_write(jas_stream_obj_t *obj, const char *buf,
117 size_t cnt);
118static long sfile_seek(jas_stream_obj_t *obj, long offset, int origin);
119static int sfile_close(jas_stream_obj_t *obj);
120
121static ssize_t file_read(jas_stream_obj_t *obj, char *buf, size_t cnt);
122static ssize_t file_write(jas_stream_obj_t *obj, const char *buf,
123 size_t cnt);
97static long file_seek(jas_stream_obj_t *obj, long offset, int origin);124static long file_seek(jas_stream_obj_t *obj, long offset, int origin);
98static int file_close(jas_stream_obj_t *obj);125static int file_close(jas_stream_obj_t *obj);
99 126
@@ -108,6 +135,13 @@ static const jas_stream_ops_t jas_stream_fileops = { · 8 unmodified lines
108 file_close135 file_close
109};136};
110 137
138static const jas_stream_ops_t jas_stream_sfileops = {
139 sfile_read,
140 sfile_write,
141 sfile_seek,
142 sfile_close
143};
144
111static const jas_stream_ops_t jas_stream_memops = {145static const jas_stream_ops_t jas_stream_memops = {
112 mem_read,146 mem_read,
113 mem_write,147 mem_write,
@@ -142,17 +176,12 @@ static jas_stream_t *jas_stream_create() · 28 unmodified lines
142 return stream;176 return stream;
143}177}
144 178
145/*179jas_stream_t *jas_stream_memopen(char *buf, size_t bufsize)
146This function will eventually replace jas_stream_memopen.
147For documentation of the interface for this function, see jas_stream.h.
148*/
149
150jas_stream_t *jas_stream_memopen2(char *buf, size_t bufsize)
151{180{
152 jas_stream_t *stream;181 jas_stream_t *stream;
153 jas_stream_memobj_t *obj;182 jas_stream_memobj_t *obj;
154 183
155 JAS_DBGLOG(100, ("jas_stream_memopen2(%p, %zu)\n", buf, bufsize));184 JAS_LOGDEBUGF(100, "jas_stream_memopen(%p, %zu)\n", buf, bufsize);
156 185
157 assert((buf && bufsize > 0) || (!buf));186 assert((buf && bufsize > 0) || (!buf));
158 187
@@ -201,8 +230,8 @@ jas_stream_t *jas_stream_memopen2(char *buf, size_t bufsize) · 42 unmodified lines
201 jas_stream_close(stream);230 jas_stream_close(stream);
202 return 0;231 return 0;
203 }232 }
204 JAS_DBGLOG(100, ("jas_stream_memopen2 buffer buf=%p myalloc=%d\n",233 JAS_LOGDEBUGF(100, "jas_stream_memopen buffer buf=%p myalloc=%d\n",
205 obj->buf_, obj->myalloc_));234 obj->buf_, obj->myalloc_);
206 235
207 if (bufsize > 0 && buf) {236 if (bufsize > 0 && buf) {
208 /* If a buffer was supplied by the caller and its length is positive,237 /* If a buffer was supplied by the caller and its length is positive,
@@ -218,40 +247,13 @@ jas_stream_t *jas_stream_memopen2(char *buf, size_t bufsize) · 9 unmodified lines
218}247}
219 248
220/*249/*
221NOTE:250This function is deprecated.
222The version of the function jas_stream_memopen only exists for backwards251It will be removed eventually.
223compatibility.
224Eventually, it should be replaced by jas_stream_memopen2.
225In retrospect, it was a very poor choice to have specified the buffer
226size parameter (bufsize) to have type int. On some machines, int may only
227be a 16-bit integer. This precludes larger-sized buffer allocations, which
228are needed in practice.
229
230If bufsize <= 0, the buffer is growable; otherwise, the buffer has a fixed
231size of bufsize.
232If buf is 0, the buffer is dynamically allocated with jas_malloc.
233If buf is not 0 and bufsize <= 0 (which is not permitted in any
234circumstances), bad things will happen (especially if the buf was not
235allocated with jas_malloc).
236*/252*/
237jas_stream_t *jas_stream_memopen(char *buf, int bufsize)253jas_stream_t *jas_stream_memopen2(char *buf, size_t bufsize)
238{254{
239 char *new_buf;255 jas_deprecated("jas_stream_memopen2 is deprecated\n");
240 size_t new_bufsize;256 return jas_stream_memopen(buf, bufsize);
241
242 JAS_DBGLOG(100, ("jas_stream_memopen(%p, %d)\n", buf, bufsize));
243 if (bufsize < 0 || (buf && bufsize <= 0)) {
244 jas_eprintf("Invalid use of jas_stream_memopen detected.\n");
245 return nil;
246 }
247 if (bufsize <= 0) {
248 new_bufsize = 0;
249 new_buf = 0;
250 } else {
251 new_bufsize = bufsize;
252 new_buf = buf;
253 }
254 return jas_stream_memopen2(new_buf, new_bufsize);
255}257}
256 258
257jas_stream_t *jas_stream_fopen(const char *filename, const char *mode)259jas_stream_t *jas_stream_fopen(const char *filename, const char *mode)
@@ -260,7 +262,7 @@ jas_stream_t *jas_stream_fopen(const char *filename, const char *mode) · 2 unmodified lines
260 jas_stream_fileobj_t *obj;262 jas_stream_fileobj_t *obj;
261 int openflags;263 int openflags;
262 264
263 JAS_DBGLOG(100, ("jas_stream_fopen(\"%s\", \"%s\")\n", filename, mode));265 JAS_LOGDEBUGF(100, "jas_stream_fopen(\"%s\", \"%s\")\n", filename, mode);
264 266
265 /* Allocate a stream object. */267 /* Allocate a stream object. */
266 if (!(stream = jas_stream_create())) {268 if (!(stream = jas_stream_create())) {
@@ -273,19 +275,25 @@ jas_stream_t *jas_stream_fopen(const char *filename, const char *mode) · 6 unmodified lines
273 /* Determine the correct flags to use for opening the file. */275 /* Determine the correct flags to use for opening the file. */
274 if ((stream->openmode_ & JAS_STREAM_READ) &&276 if ((stream->openmode_ & JAS_STREAM_READ) &&
275 (stream->openmode_ & JAS_STREAM_WRITE)) {277 (stream->openmode_ & JAS_STREAM_WRITE)) {
276 openflags = ORDWR;278 openflags = O_RDWR;
277 } else if (stream->openmode_ & JAS_STREAM_READ) {279 } else if (stream->openmode_ & JAS_STREAM_READ) {
278 openflags = OREAD;280 openflags = O_RDONLY;
279 } else if (stream->openmode_ & JAS_STREAM_WRITE) {281 } else if (stream->openmode_ & JAS_STREAM_WRITE) {
280 openflags = OWRITE;282 openflags = O_WRONLY;
281 } else {283 } else {
282 openflags = 0;284 openflags = 0;
283 }285 }
286 if (stream->openmode_ & JAS_STREAM_APPEND) {
287 openflags |= O_APPEND;
288 }
289 if (stream->openmode_ & JAS_STREAM_BINARY) {
290 openflags |= O_BINARY;
291 }
284 if (stream->openmode_ & JAS_STREAM_CREATE) {292 if (stream->openmode_ & JAS_STREAM_CREATE) {
285 openflags |= OTRUNC;293 openflags |= O_CREAT | O_TRUNC;
286 }294 }
287 295
288 openflags |= OCEXEC;296 openflags |= O_CLOEXEC;
289 297
290 /* Allocate space for the underlying file stream object. */298 /* Allocate space for the underlying file stream object. */
291 if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) {299 if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) {
@@ -294,41 +302,177 @@ jas_stream_t *jas_stream_fopen(const char *filename, const char *mode) · 2 unmodified lines
294 }302 }
295 obj->fd = -1;303 obj->fd = -1;
296 obj->flags = 0;304 obj->flags = 0;
305 obj->pathname[0] = '\0';
297 stream->obj_ = (void *) obj;306 stream->obj_ = (void *) obj;
298 307
299 /* Select the operations for a file stream object. */308 /* Select the operations for a file stream object. */
300 stream->ops_ = &jas_stream_fileops;309 stream->ops_ = &jas_stream_fileops;
301 310
302 if (stream->openmode_ & JAS_STREAM_CREATE) {
303 obj->fd = create(filename, openflags, JAS_STREAM_PERMS);
304 } else {
305 obj->fd = open(filename, openflags);
306 }
307
308 /* Open the underlying file. */311 /* Open the underlying file. */
309 if (obj->fd < 0) {312 if ((obj->fd = open(filename, openflags/*, JAS_STREAM_PERMS*/)) < 0) {
310 // Free the underlying file object, since it will not otherwise313 // Free the underlying file object, since it will not otherwise
311 // be freed.314 // be freed.
312 jas_free(obj);315 jas_free(obj);
313 jas_stream_destroy(stream);316 jas_stream_destroy(stream);
314 return 0;317 return 0;
315 }318 }
316 if (stream->openmode_ & JAS_STREAM_APPEND) {319
317 seek(obj->fd, 0, 2);320 /* By default, use full buffering for this type of stream. */
321 jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0);
322
323 return stream;
324}
325
326jas_stream_t *jas_stream_freopen(const char *path, const char *mode, FILE *fp)
327{
328 jas_stream_t *stream;
329
330 JAS_LOGDEBUGF(100, "jas_stream_freopen(\"%s\", \"%s\", %p)\n", path, mode, fp);
331
332 JAS_UNUSED(path);
333
334 /* Allocate a stream object. */
335 if (!(stream = jas_stream_create())) {
336 return 0;
318 }337 }
319 338
339 /* Parse the mode string. */
340 stream->openmode_ = jas_strtoopenmode(mode);
341
342 stream->obj_ = JAS_CAST(void *, fp);
343
344 /* Select the operations for a file stream object. */
345 stream->ops_ = &jas_stream_sfileops;
346
320 /* By default, use full buffering for this type of stream. */347 /* By default, use full buffering for this type of stream. */
321 jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0);348 jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0);
322 349
323 return stream;350 return stream;
324}351}
325 352
353#ifndef _WIN32
354
355/**
356 * Copy the absolute path of the directory for temporary files to the
357 * given buffer (without a null terminator), including a trailing path
358 * separator.
359 *
360 * @return the number of characters copied to the buffer or 0 on error
361 */
362static size_t get_temp_directory(char *buffer, size_t size)
363{
364 const char *tmpdir = getenv("TMPDIR");
365 if (tmpdir == NULL) {
366 tmpdir = "/tmp";
367 }
368
369 size_t length = strlen(tmpdir);
370 if (length + 1 > size) {
371 return 0;
372 }
373
374 memcpy(buffer, tmpdir, length);
375 buffer[length++] = '/';
376 return length;
377}
378
379#endif /* !_WIN32 */
380
381/**
382 * Generate a template for mkstemp().
383 *
384 * @return 0 on success, -1 on error
385 */
386static int make_mkstemp_template(char *buffer, size_t size)
387{
388#ifdef _WIN32
389 char temp_directory[MAX_PATH];
390 if (GetTempPathA(sizeof(temp_directory), temp_directory) == 0) {
391 return -1;
392 }
393 JAS_UNUSED(size);
394 return GetTempFileNameA(temp_directory, "jasper", 0, buffer) > 0
395 ? 0 : -1;
396#else
397 static const char base[] = "jasper.XXXXXX";
398 size_t length = get_temp_directory(buffer, size);
399 if (length == 0 || length + sizeof(base) >= size) {
400 return -1;
401 }
402 memcpy(buffer + length, base, sizeof(base));
403 return 0;
404#endif
405}
406
407/**
408 * A wrapper for mkstemp() which generates a template for mkstemp()
409 * before calling the function.
410 *
411 * @return a non-negative file descriptor on success, -1 on error
412 */
413static int easy_mkstemp(char *buffer, size_t size)
414{
415 JAS_UNUSED(buffer);
416 JAS_UNUSED(size);
417 return -1;
418}
419
420jas_stream_t *jas_stream_tmpfile()
421{
422 jas_stream_t *stream;
423 jas_stream_fileobj_t *obj;
424
425 JAS_LOGDEBUGF(100, "jas_stream_tmpfile()\n");
426
427 if (!(stream = jas_stream_create())) {
428 return 0;
429 }
430
431 /* A temporary file stream is always opened for both reading and
432 writing in binary mode. */
433 stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY;
434
435 /* Allocate memory for the underlying temporary file object. */
436 if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) {
437 jas_stream_destroy(stream);
438 return 0;
439 }
440 obj->fd = -1;
441 obj->flags = 0;
442 obj->pathname[0] = '\0';
443 stream->obj_ = obj;
444
445 /* Create the temporary file. */
446 if ((obj->fd = easy_mkstemp(obj->pathname, sizeof(obj->pathname))) < 0) {
447 jas_stream_destroy(stream);
448 return 0;
449 }
450
451 /* Unlink the file so that it will disappear if the program
452 terminates abnormally. */
453 /* Under UNIX, one can unlink an open file and continue to do I/O
454 on it. Not all operating systems support this functionality, however.
455 For example, under Microsoft Windows the unlink operation will fail,
456 since the file is open. */
457 if (*obj->pathname != 0 && unlink(obj->pathname) < 0) {
458 /* We will try unlinking the file again after it is closed. */
459 obj->flags |= JAS_STREAM_FILEOBJ_DELONCLOSE;
460 }
461
462 /* Use full buffering. */
463 jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0);
464
465 stream->ops_ = &jas_stream_fileops;
466
467 return stream;
468}
469
326jas_stream_t *jas_stream_fdopen(int fd, const char *mode)470jas_stream_t *jas_stream_fdopen(int fd, const char *mode)
327{471{
328 jas_stream_t *stream;472 jas_stream_t *stream;
329 jas_stream_fileobj_t *obj;473 jas_stream_fileobj_t *obj;
330 474
331 JAS_DBGLOG(100, ("jas_stream_fdopen(%d, \"%s\")\n", fd, mode));475 JAS_LOGDEBUGF(100, "jas_stream_fdopen(%d, \"%s\")\n", fd, mode);
332 476
333 /* Allocate a stream object. */477 /* Allocate a stream object. */
334 if (!(stream = jas_stream_create())) {478 if (!(stream = jas_stream_create())) {
@@ -338,7 +482,7 @@ jas_stream_t *jas_stream_fdopen(int fd, const char *mode) · 3 unmodified lines
338 /* Parse the mode string. */482 /* Parse the mode string. */
339 stream->openmode_ = jas_strtoopenmode(mode);483 stream->openmode_ = jas_strtoopenmode(mode);
340 484
341#if defined(WIN32)485#if defined(_WIN32) || defined(JAS_HAVE_IO_H)
342 /* Argh!!! Someone ought to banish text mode (i.e., O_TEXT) to the486 /* Argh!!! Someone ought to banish text mode (i.e., O_TEXT) to the
343 greatest depths of purgatory! */487 greatest depths of purgatory! */
344 /* Ensure that the file descriptor is in binary mode, if the caller488 /* Ensure that the file descriptor is in binary mode, if the caller
@@ -362,6 +506,7 @@ jas_stream_t *jas_stream_fdopen(int fd, const char *mode) · 17 unmodified lines
362 }506 }
363 obj->fd = fd;507 obj->fd = fd;
364 obj->flags = 0;508 obj->flags = 0;
509 obj->pathname[0] = '\0';
365 stream->obj_ = (void *) obj;510 stream->obj_ = (void *) obj;
366 511
367 /* Do not close the underlying file descriptor when the stream is512 /* Do not close the underlying file descriptor when the stream is
@@ -379,13 +524,13 @@ jas_stream_t *jas_stream_fdopen(int fd, const char *mode) · 11 unmodified lines
379 524
380static void jas_stream_destroy(jas_stream_t *stream)525static void jas_stream_destroy(jas_stream_t *stream)
381{526{
382 JAS_DBGLOG(100, ("jas_stream_destroy(%p)\n", stream));527 JAS_LOGDEBUGF(100, "jas_stream_destroy(%p)\n", stream);
383 528
384 /* If the memory for the buffer was allocated with malloc, free529 /* If the memory for the buffer was allocated with malloc, free
385 this memory. */530 this memory. */
386 if ((stream->bufmode_ & JAS_STREAM_FREEBUF) && stream->bufbase_) {531 if ((stream->bufmode_ & JAS_STREAM_FREEBUF) && stream->bufbase_) {
387 JAS_DBGLOG(100, ("jas_stream_destroy freeing buffer %p\n",532 JAS_LOGDEBUGF(100, "jas_stream_destroy freeing buffer %p\n",
388 stream->bufbase_));533 stream->bufbase_);
389 jas_free(stream->bufbase_);534 jas_free(stream->bufbase_);
390 stream->bufbase_ = 0;535 stream->bufbase_ = 0;
391 }536 }
@@ -394,7 +539,7 @@ static void jas_stream_destroy(jas_stream_t *stream) · 2 unmodified lines
394 539
395int jas_stream_close(jas_stream_t *stream)540int jas_stream_close(jas_stream_t *stream)
396{541{
397 JAS_DBGLOG(100, ("jas_stream_close(%p)\n", stream));542 JAS_LOGDEBUGF(100, "jas_stream_close(%p)\n", stream);
398 543
399 /* Flush buffer if necessary. */544 /* Flush buffer if necessary. */
400 jas_stream_flush(stream);545 jas_stream_flush(stream);
@@ -451,16 +596,16 @@ int jas_stream_ungetc(jas_stream_t *stream, int c) · 50 unmodified lines
451 return 0;596 return 0;
452}597}
453 598
454/* FIXME integral type */599size_t jas_stream_read(jas_stream_t *stream, void *buf, size_t cnt)
455unsigned jas_stream_read(jas_stream_t *stream, void *buf, unsigned cnt)
456{600{
457 int c;601 int c;
458 char *bufptr;602 char *bufptr;
459 603
460 JAS_DBGLOG(100, ("jas_stream_read(%p, %p, %u)\n", stream, buf, cnt));604 JAS_LOGDEBUGF(100, "jas_stream_read(%p, %p, %zu)\n", stream, buf, cnt);
461 605
462 if (cnt == 0)606 if (cnt == 0) {
463 return 0;607 return 0;
608 }
464 609
465 bufptr = buf;610 bufptr = buf;
466 611
@@ -468,11 +613,13 @@ unsigned jas_stream_read(jas_stream_t *stream, void *buf, unsigned cnt) · 1 unmodified line
468 jas_stream_is_input_buffer_empty(stream)) {613 jas_stream_is_input_buffer_empty(stream)) {
469 /* fast path for unbuffered streams */614 /* fast path for unbuffered streams */
470 615
471 if ((stream->flags_ & JAS_STREAM_ERRMASK) != 0)616 if ((stream->flags_ & JAS_STREAM_ERRMASK) != 0) {
472 return 0;617 return 0;
618 }
473 619
474 if ((stream->openmode_ & JAS_STREAM_READ) == 0)620 if ((stream->openmode_ & JAS_STREAM_READ) == 0) {
475 return 0;621 return 0;
622 }
476 623
477 assert((stream->bufmode_ & JAS_STREAM_WRBUF) == 0);624 assert((stream->bufmode_ & JAS_STREAM_WRBUF) == 0);
478 625
@@ -502,29 +649,32 @@ unsigned jas_stream_read(jas_stream_t *stream, void *buf, unsigned cnt) · 23 unmodified lines
502 return n;649 return n;
503}650}
504 651
652/* TODO: The return type should probably be changed to size_t. */
505unsigned jas_stream_peek(jas_stream_t *stream, void *buf, size_t cnt)653unsigned jas_stream_peek(jas_stream_t *stream, void *buf, size_t cnt)
506{654{
507 char *bufptr = buf;655 char *bufptr = buf;
508 656
509 const unsigned n = jas_stream_read(stream, bufptr, cnt);657 const size_t n = jas_stream_read(stream, bufptr, cnt);
510 658
511 /* Put the characters read back onto the stream. */659 /* Put the characters read back onto the stream. */
512 for (unsigned i = n; i-- > 0;)660 for (size_t i = n; i-- > 0;) {
513 if (jas_stream_ungetc(stream, bufptr[i]) == EOF)661 if (jas_stream_ungetc(stream, bufptr[i]) == EOF) {
514 return 0;662 return 0;
663 }
664 }
515 665
516 return n;666 return n;
517}667}
518 668
519/* FIXME integral type */669size_t jas_stream_write(jas_stream_t *stream, const void *buf, size_t cnt)
520unsigned jas_stream_write(jas_stream_t *stream, const void *buf, unsigned cnt)
521{670{
522 const char *bufptr;671 const char *bufptr;
523 672
524 JAS_DBGLOG(100, ("jas_stream_write(%p, %p, %d)\n", stream, buf, cnt));673 JAS_LOGDEBUGF(100, "jas_stream_write(%p, %p, %zu)\n", stream, buf, cnt);
525 674
526 if (cnt == 0)675 if (cnt == 0) {
527 return 0;676 return 0;
677 }
528 678
529 bufptr = buf;679 bufptr = buf;
530 680
@@ -533,8 +683,9 @@ unsigned jas_stream_write(jas_stream_t *stream, const void *buf, unsigned cnt) · 2 unmodified lines
533 683
534 /* need to flush the output buffer before we do a raw684 /* need to flush the output buffer before we do a raw
535 write */685 write */
536 if (jas_stream_flushbuf(stream, EOF))686 if (jas_stream_flushbuf(stream, EOF)) {
537 return 0;687 return 0;
688 }
538 689
539 stream->bufmode_ |= JAS_STREAM_WRBUF;690 stream->bufmode_ |= JAS_STREAM_WRBUF;
540 691
@@ -570,7 +721,7 @@ int jas_stream_printf(jas_stream_t *stream, const char *fmt, ...) · 29 unmodified lines
570 int ret;721 int ret;
571 722
572 va_start(ap, fmt);723 va_start(ap, fmt);
573 ret = vsnprint(buf, sizeof buf, fmt, ap);724 ret = vsnprintf(buf, sizeof buf, fmt, ap);
574 jas_stream_puts(stream, buf);725 jas_stream_puts(stream, buf);
575 va_end(ap);726 va_end(ap);
576 return ret;727 return ret;
@@ -595,7 +746,7 @@ char *jas_stream_gets(jas_stream_t *stream, char *buf, int bufsize) · 18 unmodified lines
595 char *bufptr;746 char *bufptr;
596 assert(bufsize > 0);747 assert(bufsize > 0);
597 748
598 JAS_DBGLOG(100, ("jas_stream_gets(%p, %p, %d)\n", stream, buf, bufsize));749 JAS_LOGDEBUGF(100, "jas_stream_gets(%p, %p, %d)\n", stream, buf, bufsize);
599 750
600 bufptr = buf;751 bufptr = buf;
601 while (bufsize > 1) {752 while (bufsize > 1) {
@@ -612,17 +763,10 @@ char *jas_stream_gets(jas_stream_t *stream, char *buf, int bufsize) · 10 unmodified lines
612 return buf;763 return buf;
613}764}
614 765
615/* FIXME integral type */766ssize_t jas_stream_gobble(jas_stream_t *stream, size_t n)
616int jas_stream_gobble(jas_stream_t *stream, int n)
617{767{
618 int m;768 size_t m;
619 769 JAS_LOGDEBUGF(100, "jas_stream_gobble(%p, %zu)\n", stream, n);
620 JAS_DBGLOG(100, ("jas_stream_gobble(%p, %d)\n", stream, n));
621
622 if (n < 0) {
623 jas_eprintf("negative count for jas_stream_gobble\n");
624 return 0;
625 }
626 for (m = n; m > 0; --m) {770 for (m = n; m > 0; --m) {
627 if (jas_stream_getc(stream) == EOF) {771 if (jas_stream_getc(stream) == EOF) {
628 return n - m;772 return n - m;
@@ -631,20 +775,14 @@ int jas_stream_gobble(jas_stream_t *stream, int n) · 2 unmodified lines
631 return n;775 return n;
632}776}
633 777
634/* FIXME integral type */778ssize_t jas_stream_pad(jas_stream_t *stream, size_t n, int c)
635int jas_stream_pad(jas_stream_t *stream, int n, int c)
636{779{
637 int m;780 size_t m;
638 781 JAS_LOGDEBUGF(100, "jas_stream_pad(%p, %zu, %d)\n", stream, n, c);
639 JAS_DBGLOG(100, ("jas_stream_pad(%p, %d, %d)\n", stream, n, c));
640
641 if (n < 0) {
642 jas_eprintf("negative count for jas_stream_pad\n");
643 return 0;
644 }
645 for (m = n; m > 0; --m) {782 for (m = n; m > 0; --m) {
646 if (jas_stream_putc(stream, c) == EOF)783 if (jas_stream_putc(stream, c) == EOF) {
647 return n - m;784 return n - m;
785 }
648 }786 }
649 return n;787 return n;
650}788}
@@ -658,7 +796,7 @@ int jas_stream_isseekable(jas_stream_t *stream) · 7 unmodified lines
658 if (stream->ops_ == &jas_stream_memops) {796 if (stream->ops_ == &jas_stream_memops) {
659 return 1;797 return 1;
660 } else if (stream->ops_ == &jas_stream_fileops) {798 } else if (stream->ops_ == &jas_stream_fileops) {
661 if ((*stream->ops_->seek_)(stream->obj_, 0, 1) < 0) {799 if ((*stream->ops_->seek_)(stream->obj_, 0, SEEK_CUR) < 0) {
662 return 0;800 return 0;
663 }801 }
664 return 1;802 return 1;
@@ -669,16 +807,15 @@ int jas_stream_isseekable(jas_stream_t *stream) · 4 unmodified lines
669 807
670int jas_stream_rewind(jas_stream_t *stream)808int jas_stream_rewind(jas_stream_t *stream)
671{809{
672 JAS_DBGLOG(100, ("jas_stream_rewind(%p)\n", stream));810 JAS_LOGDEBUGF(100, "jas_stream_rewind(%p)\n", stream);
673 return jas_stream_seek(stream, 0, 0);811 return jas_stream_seek(stream, 0, SEEK_SET);
674}812}
675 813
676long jas_stream_seek(jas_stream_t *stream, long offset, int origin)814long jas_stream_seek(jas_stream_t *stream, long offset, int origin)
677{815{
678 long newpos;816 long newpos;
679 817
680 JAS_DBGLOG(100, ("jas_stream_seek(%p, %ld, %d)\n", stream, offset,818 JAS_LOGDEBUGF(100, "jas_stream_seek(%p, %ld, %d)\n", stream, offset, origin);
681 origin));
682 819
683 /* The buffer cannot be in use for both reading and writing. */820 /* The buffer cannot be in use for both reading and writing. */
684 assert(!((stream->bufmode_ & JAS_STREAM_RDBUF) && (stream->bufmode_ &821 assert(!((stream->bufmode_ & JAS_STREAM_RDBUF) && (stream->bufmode_ &
@@ -688,7 +825,7 @@ long jas_stream_seek(jas_stream_t *stream, long offset, int origin) · 3 unmodified lines
688 stream->flags_ &= ~JAS_STREAM_EOF;825 stream->flags_ &= ~JAS_STREAM_EOF;
689 826
690 if (stream->bufmode_ & JAS_STREAM_RDBUF) {827 if (stream->bufmode_ & JAS_STREAM_RDBUF) {
691 if (origin == 1) {828 if (origin == SEEK_CUR) {
692 offset -= stream->cnt_;829 offset -= stream->cnt_;
693 }830 }
694 } else if (stream->bufmode_ & JAS_STREAM_WRBUF) {831 } else if (stream->bufmode_ & JAS_STREAM_WRBUF) {
@@ -713,7 +850,7 @@ long jas_stream_tell(jas_stream_t *stream) · 18 unmodified lines
713 int adjust;850 int adjust;
714 int offset;851 int offset;
715 852
716 JAS_DBGLOG(100, ("jas_stream_tell(%p)\n", stream));853 JAS_LOGDEBUGF(100, "jas_stream_tell(%p)\n", stream);
717 854
718 if (stream->bufmode_ & JAS_STREAM_RDBUF) {855 if (stream->bufmode_ & JAS_STREAM_RDBUF) {
719 adjust = -stream->cnt_;856 adjust = -stream->cnt_;
@@ -723,7 +860,7 @@ long jas_stream_tell(jas_stream_t *stream) · 3 unmodified lines
723 adjust = 0;860 adjust = 0;
724 }861 }
725 862
726 if ((offset = (*stream->ops_->seek_)(stream->obj_, 0, 1)) < 0) {863 if ((offset = (*stream->ops_->seek_)(stream->obj_, 0, SEEK_CUR)) < 0) {
727 return -1;864 return -1;
728 }865 }
729 866
@@ -910,10 +1047,9 @@ static int jas_strtoopenmode(const char *s) · 180 unmodified lines
910 return openmode;1047 return openmode;
911}1048}
912 1049
913/* FIXME integral type */1050int jas_stream_copy(jas_stream_t *out, jas_stream_t *in, ssize_t n)
914int jas_stream_copy(jas_stream_t *out, jas_stream_t *in, int n)
915{1051{
916 int m;1052 ssize_t m;
917 1053
918 const bool all = n < 0;1054 const bool all = n < 0;
919 1055
@@ -921,14 +1057,14 @@ int jas_stream_copy(jas_stream_t *out, jas_stream_t *in, int n) · 1 unmodified line
921 1057
922 m = n;1058 m = n;
923 while (all || m > 0) {1059 while (all || m > 0) {
924 unsigned nbytes = jas_stream_read(in, buffer,1060 size_t nbytes = jas_stream_read(in, buffer,
925 JAS_MIN((size_t)m, sizeof(buffer)));1061 JAS_MIN((size_t)m, sizeof(buffer)));
926 if (nbytes == 0)1062 if (nbytes == 0) {
927 return !all || jas_stream_error(in) ? -1 : 0;1063 return !all || jas_stream_error(in) ? -1 : 0;
928 1064 }
929 if (jas_stream_write(out, buffer, nbytes) != nbytes)1065 if (jas_stream_write(out, buffer, nbytes) != nbytes) {
930 return -1;1066 return -1;
931 1067 }
932 m -= nbytes;1068 m -= nbytes;
933 }1069 }
934 1070
@@ -945,7 +1081,7 @@ long jas_stream_setrwcount(jas_stream_t *stream, long rwcnt) · 10 unmodified lines
945 return old;1081 return old;
946}1082}
947 1083
948JAS_DLLEXPORT1084JAS_EXPORT
949long jas_stream_setrwlimit(jas_stream_t *stream, long rwlimit)1085long jas_stream_setrwlimit(jas_stream_t *stream, long rwlimit)
950{1086{
951 long old;1087 long old;
@@ -955,6 +1091,57 @@ long jas_stream_setrwlimit(jas_stream_t *stream, long rwlimit) · 3 unmodified lines
955 return old;1091 return old;
956}1092}
957 1093
1094/* FIXME integral type */
1095int jas_stream_display(jas_stream_t *stream, FILE *fp, int n)
1096{
1097 unsigned char buf[16];
1098 int i;
1099 int j;
1100 int m;
1101 int c;
1102 int display;
1103 int cnt;
1104
1105 cnt = n - (n % 16);
1106 display = 1;
1107
1108 for (i = 0; i < n; i += 16) {
1109 if (n > 16 && i > 0) {
1110 display = (i >= cnt) ? 1 : 0;
1111 }
1112 if (display) {
1113 fprintf(fp, "%08x:", i);
1114 }
1115 m = JAS_MIN(n - i, 16);
1116 for (j = 0; j < m; ++j) {
1117 if ((c = jas_stream_getc(stream)) == EOF) {
1118 return -1;
1119 }
1120 buf[j] = c;
1121 }
1122 if (display) {
1123 for (j = 0; j < m; ++j) {
1124 fprintf(fp, " %02x", buf[j]);
1125 }
1126 fputc(' ', fp);
1127 for (; j < 16; ++j) {
1128 fprintf(fp, " ");
1129 }
1130 for (j = 0; j < m; ++j) {
1131 if (isprint(buf[j])) {
1132 fputc(buf[j], fp);
1133 } else {
1134 fputc(' ', fp);
1135 }
1136 }
1137 fprintf(fp, "\n");
1138 }
1139
1140
1141 }
1142 return 0;
1143}
1144
958long jas_stream_length(jas_stream_t *stream)1145long jas_stream_length(jas_stream_t *stream)
959{1146{
960 long oldpos;1147 long oldpos;
@@ -962,13 +1149,13 @@ long jas_stream_length(jas_stream_t *stream) · 1 unmodified line
962 if ((oldpos = jas_stream_tell(stream)) < 0) {1149 if ((oldpos = jas_stream_tell(stream)) < 0) {
963 return -1;1150 return -1;
964 }1151 }
965 if (jas_stream_seek(stream, 0, 2) < 0) {1152 if (jas_stream_seek(stream, 0, SEEK_END) < 0) {
966 return -1;1153 return -1;
967 }1154 }
968 if ((pos = jas_stream_tell(stream)) < 0) {1155 if ((pos = jas_stream_tell(stream)) < 0) {
969 return -1;1156 return -1;
970 }1157 }
971 if (jas_stream_seek(stream, oldpos, 0) < 0) {1158 if (jas_stream_seek(stream, oldpos, SEEK_SET) < 0) {
972 return -1;1159 return -1;
973 }1160 }
974 return pos;1161 return pos;
@@ -978,13 +1165,12 @@ long jas_stream_length(jas_stream_t *stream) · 3 unmodified lines
978* Memory stream object.1165* Memory stream object.
979\******************************************************************************/1166\******************************************************************************/
980 1167
981/* FIXME integral type */1168static ssize_t mem_read(jas_stream_obj_t *obj, char *buf, size_t cnt)
982static int mem_read(jas_stream_obj_t *obj, char *buf, unsigned cnt)
983{1169{
984 jas_stream_memobj_t *m;1170 jas_stream_memobj_t *m;
985 assert(buf);1171 assert(buf);
986 1172
987 JAS_DBGLOG(100, ("mem_read(%p, %p, %u)\n", obj, buf, cnt));1173 JAS_LOGDEBUGF(100, "mem_read(%p, %p, %zu)\n", obj, buf, cnt);
988 m = (jas_stream_memobj_t *)obj;1174 m = (jas_stream_memobj_t *)obj;
989 size_t n = m->len_ - m->pos_;1175 size_t n = m->len_ - m->pos_;
990 cnt = JAS_MIN(n, cnt);1176 cnt = JAS_MIN(n, cnt);
@@ -997,11 +1183,9 @@ static int mem_resize(jas_stream_memobj_t *m, size_t bufsize) · 6 unmodified lines
997{1183{
998 unsigned char *buf;1184 unsigned char *buf;
999 1185
1000 //assert(m->buf_);1186 JAS_LOGDEBUGF(100, "mem_resize(%p, %zu)\n", m, bufsize);
1001
1002 JAS_DBGLOG(100, ("mem_resize(%p, %zu)\n", m, bufsize));
1003 if (!bufsize) {1187 if (!bufsize) {
1004 jas_eprintf(1188 jas_logerrorf(
1005 "mem_resize was not really designed to handle a buffer of size 0\n"1189 "mem_resize was not really designed to handle a buffer of size 0\n"
1006 "This may not work.\n"1190 "This may not work.\n"
1007 );1191 );
@@ -1009,17 +1193,17 @@ static int mem_resize(jas_stream_memobj_t *m, size_t bufsize) · 1 unmodified line
1009 1193
1010 if (!(buf = jas_realloc2(m->buf_, bufsize, sizeof(unsigned char))) &&1194 if (!(buf = jas_realloc2(m->buf_, bufsize, sizeof(unsigned char))) &&
1011 bufsize) {1195 bufsize) {
1012 JAS_DBGLOG(100, ("mem_resize realloc failed\n"));1196 JAS_LOGDEBUGF(100, "mem_resize realloc failed\n");
1013 return -1;1197 return -1;
1014 }1198 }
1015 JAS_DBGLOG(100, ("mem_resize realloc succeeded\n"));1199 JAS_LOGDEBUGF(100, "mem_resize realloc succeeded\n");
1016 m->buf_ = buf;1200 m->buf_ = buf;
1017 m->bufsize_ = bufsize;1201 m->bufsize_ = bufsize;
1018 return 0;1202 return 0;
1019}1203}
1020 1204
1021/* FIXME integral type */1205static ssize_t mem_write(jas_stream_obj_t *obj, const char *buf,
1022static int mem_write(jas_stream_obj_t *obj, const char *buf, unsigned cnt)1206 size_t cnt)
1023{1207{
1024 size_t n;1208 size_t n;
1025 jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj;1209 jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj;
@@ -1028,19 +1212,19 @@ static int mem_write(jas_stream_obj_t *obj, const char *buf, unsigned cnt) · 2 unmodified lines
1028 1212
1029 assert(buf);1213 assert(buf);
1030 1214
1031 JAS_DBGLOG(100, ("mem_write(%p, %p, %u)\n", obj, buf, cnt));1215 JAS_LOGDEBUGF(100, "mem_write(%p, %p, %zu)\n", obj, buf, cnt);
1032 newpos = m->pos_ + cnt;1216 newpos = m->pos_ + cnt;
1033 if (newpos > m->bufsize_ && m->growable_) {1217 if (newpos > m->bufsize_ && m->growable_) {
1034 newbufsize = m->bufsize_;1218 newbufsize = m->bufsize_;
1035 while (newbufsize < newpos) {1219 while (newbufsize < newpos) {
1036 //newbufsize <<= 1;1220 /* Attempt to double the buffer size. */
1037 if (!jas_safe_size_mul(newbufsize, 2, &newbufsize)) {1221 if (!jas_safe_size_mul(newbufsize, 2, &newbufsize)) {
1038 JAS_DBGLOG(100, ("new buffer size would cause overflow\n"));1222 JAS_LOGDEBUGF(100, "new buffer size would cause overflow\n");
1039 return -1;1223 return -1;
1040 }1224 }
1041 }1225 }
1042 JAS_DBGLOG(100, ("mem_write resizing from %d to %zu\n", m->bufsize_,1226 JAS_LOGDEBUGF(100, "mem_write resizing from %d to %zu\n", m->bufsize_,
1043 newbufsize));1227 newbufsize);
1044 assert(newbufsize > 0);1228 assert(newbufsize > 0);
1045 if (mem_resize(m, newbufsize)) {1229 if (mem_resize(m, newbufsize)) {
1046 return -1;1230 return -1;
@@ -1078,15 +1262,15 @@ static long mem_seek(jas_stream_obj_t *obj, long offset, int origin) · 31 unmodified lines
1078 jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj;1262 jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj;
1079 long newpos;1263 long newpos;
1080 1264
1081 JAS_DBGLOG(100, ("mem_seek(%p, %ld, %d)\n", obj, offset, origin));1265 JAS_LOGDEBUGF(100, "mem_seek(%p, %ld, %d)\n", obj, offset, origin);
1082 switch (origin) {1266 switch (origin) {
1083 case 0:1267 case SEEK_SET:
1084 newpos = offset;1268 newpos = offset;
1085 break;1269 break;
1086 case 2:1270 case SEEK_END:
1087 newpos = m->len_ - offset;1271 newpos = m->len_ - offset;
1088 break;1272 break;
1089 case 1:1273 case SEEK_CUR:
1090 newpos = m->pos_ + offset;1274 newpos = m->pos_ + offset;
1091 break;1275 break;
1092 default:1276 default:
@@ -1104,11 +1288,11 @@ static int mem_close(jas_stream_obj_t *obj) · 11 unmodified lines
1104{1288{
1105 jas_stream_memobj_t *m;1289 jas_stream_memobj_t *m;
1106 1290
1107 JAS_DBGLOG(100, ("mem_close(%p)\n", obj));1291 JAS_LOGDEBUGF(100, "mem_close(%p)\n", obj);
1108 m = (jas_stream_memobj_t *)obj;1292 m = (jas_stream_memobj_t *)obj;
1109 JAS_DBGLOG(100, ("mem_close myalloc=%d\n", m->myalloc_));1293 JAS_LOGDEBUGF(100, "mem_close myalloc=%d\n", m->myalloc_);
1110 if (m->myalloc_ && m->buf_) {1294 if (m->myalloc_ && m->buf_) {
1111 JAS_DBGLOG(100, ("mem_close freeing buffer %p\n", m->buf_));1295 JAS_LOGDEBUGF(100, "mem_close freeing buffer %p\n", m->buf_);
1112 jas_free(m->buf_);1296 jas_free(m->buf_);
1113 m->buf_ = 0;1297 m->buf_ = 0;
1114 }1298 }
@@ -1120,20 +1304,19 @@ static int mem_close(jas_stream_obj_t *obj) · 5 unmodified lines
1120* File stream object.1304* File stream object.
1121\******************************************************************************/1305\******************************************************************************/
1122 1306
1123/* FIXME integral type */1307static ssize_t file_read(jas_stream_obj_t *obj, char *buf, size_t cnt)
1124static int file_read(jas_stream_obj_t *obj, char *buf, unsigned cnt)
1125{1308{
1126 jas_stream_fileobj_t *fileobj;1309 jas_stream_fileobj_t *fileobj;
1127 JAS_DBGLOG(100, ("file_read(%p, %p, %u)\n", obj, buf, cnt));1310 JAS_LOGDEBUGF(100, "file_read(%p, %p, %zu)\n", obj, buf, cnt);
1128 fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);1311 fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);
1129 return read(fileobj->fd, buf, cnt);1312 return read(fileobj->fd, buf, cnt);
1130}1313}
1131 1314
1132/* FIXME integral type */1315static ssize_t file_write(jas_stream_obj_t *obj, const char *buf,
1133static int file_write(jas_stream_obj_t *obj, const char *buf, unsigned cnt)1316 size_t cnt)
1134{1317{
1135 jas_stream_fileobj_t *fileobj;1318 jas_stream_fileobj_t *fileobj;
1136 JAS_DBGLOG(100, ("file_write(%p, %p, %u)\n", obj, buf, cnt));1319 JAS_LOGDEBUGF(100, "file_write(%p, %p, %zu)\n", obj, buf, cnt);
1137 fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);1320 fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);
1138 return write(fileobj->fd, buf, cnt);1321 return write(fileobj->fd, buf, cnt);
1139}1322}
@@ -1142,18 +1325,91 @@ static int file_write(jas_stream_obj_t *obj, const char *buf, unsigned cnt) · 2 unmodified lines
1142static long file_seek(jas_stream_obj_t *obj, long offset, int origin)1325static long file_seek(jas_stream_obj_t *obj, long offset, int origin)
1143{1326{
1144 jas_stream_fileobj_t *fileobj;1327 jas_stream_fileobj_t *fileobj;
1145 JAS_DBGLOG(100, ("file_seek(%p, %ld, %d)\n", obj, offset, origin));1328 JAS_LOGDEBUGF(100, "file_seek(%p, %ld, %d)\n", obj, offset, origin);
1146 fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);1329 fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);
1147 return seek(fileobj->fd, offset, origin);1330 return lseek(fileobj->fd, offset, origin);
1148}1331}
1149 1332
1150static int file_close(jas_stream_obj_t *obj)1333static int file_close(jas_stream_obj_t *obj)
1151{1334{
1152 int ret;1335 int ret = 0;
1153 jas_stream_fileobj_t *fileobj;1336 jas_stream_fileobj_t *fileobj;
1154 JAS_DBGLOG(100, ("file_close(%p)\n", obj));1337 JAS_LOGDEBUGF(100, "file_close(%p)\n", obj);
1155 fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);1338 fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);
1156 ret = close(fileobj->fd);1339 if (!(fileobj->flags & JAS_STREAM_FILEOBJ_NOCLOSE)) {
1340 ret = close(fileobj->fd);
1341 if (fileobj->flags & JAS_STREAM_FILEOBJ_DELONCLOSE) {
1342 unlink(fileobj->pathname);
1343 }
1344 }
1157 jas_free(fileobj);1345 jas_free(fileobj);
1158 return ret;1346 return ret;
1159}1347}
1348
1349/******************************************************************************\
1350* Stdio file stream object.
1351\******************************************************************************/
1352
1353static ssize_t sfile_read(jas_stream_obj_t *obj, char *buf, size_t cnt)
1354{
1355 FILE *fp;
1356 size_t n;
1357 int result;
1358 JAS_LOGDEBUGF(100, "sfile_read(%p, %p, %zu)\n", obj, buf, cnt);
1359 fp = JAS_CAST(FILE *, obj);
1360#if 0
1361 n = fread(buf, 1, cnt, fp);
1362 if (n != cnt) {
1363 result = (!ferror(fp) && feof(fp)) ? n : -1;
1364 } else {
1365 result = n;
1366 }
1367#else
1368 if (ferror(fp)) {
1369 result = -1;
1370 } else {
1371 n = fread(buf, 1, cnt, fp);
1372 return n;
1373 }
1374#endif
1375 return result;
1376}
1377
1378static ssize_t sfile_write(jas_stream_obj_t *obj, const char *buf,
1379 size_t cnt)
1380{
1381 FILE *fp;
1382 size_t n;
1383 JAS_LOGDEBUGF(100, "sfile_write(%p, %p, %zu)\n", obj, buf, cnt);
1384 fp = JAS_CAST(FILE *, obj);
1385 ssize_t result;
1386#if 0
1387 n = fwrite(buf, 1, cnt, fp);
1388 return (n != cnt) ? (-1) : cnt;
1389#else
1390 if (ferror(fp)) {
1391 result = -1;
1392 } else {
1393 n = fwrite(buf, 1, cnt, fp);
1394 result = n;
1395 }
1396 return result;
1397#endif
1398}
1399
1400/* FIXME integral type */
1401static long sfile_seek(jas_stream_obj_t *obj, long offset, int origin)
1402{
1403 FILE *fp;
1404 JAS_LOGDEBUGF(100, "sfile_seek(%p, %ld, %d)\n", obj, offset, origin);
1405 fp = JAS_CAST(FILE *, obj);
1406 return fseek(fp, offset, origin);
1407}
1408
1409static int sfile_close(jas_stream_obj_t *obj)
1410{
1411 FILE *fp;
1412 JAS_LOGDEBUGF(100, "sfile_close(%p)\n", obj);
1413 fp = JAS_CAST(FILE *, obj);
1414 return fclose(fp);
1415}
jas_string.c+216−0
@@ -0,0 +1,216 @@
1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2002 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64/*
65 * String Library
66 *
67 * $Id$
68 */
69
70/******************************************************************************\
71* Includes
72\******************************************************************************/
73
74#define JAS_FOR_INTERNAL_USE_ONLY
75
76#include "jasper/jas_string.h"
77#include "jasper/jas_malloc.h"
78#include "jasper/jas_debug.h"
79
80/******************************************************************************\
81* Miscellaneous Functions
82\******************************************************************************/
83
84/* This function is equivalent to the popular but non-standard (and
85 not-always-available) strdup function. */
86
87char *jas_strdup(const char *s)
88{
89 size_t n;
90 char *p;
91 n = strlen(s) + 1;
92 if (!(p = jas_malloc(n))) {
93 return 0;
94 }
95 strcpy(p, s);
96 return p;
97}
98
99char *jas_strtok(char *s, const char *delim, char **save_ptr)
100{
101#if 1
102 char *result;
103 char *end;
104 if (!s) {
105 s = *save_ptr;
106 }
107 if (*s != '\0') {
108 s += strspn(s, delim);
109 if (*s != '\0') {
110 end = s + strcspn(s, delim);
111 if (*end == '\0') {
112 *save_ptr = end;
113 } else {
114 *end = '\0';
115 *save_ptr = end + 1;
116 }
117 result = s;
118 } else {
119 *save_ptr = s;
120 result = 0;
121 }
122 } else {
123 *save_ptr = s;
124 result = 0;
125 }
126 return result;
127#else
128 return strtok_r(str, delim, save_ptr);
129#endif
130}
131
132JAS_EXPORT
133int jas_stringtokenize(const char *string, const char *delim,
134 char ***tokens_buf, size_t *max_tokens_buf, size_t *num_tokens_buf)
135{
136 char **tokens = 0;
137 size_t max_tokens = 0;
138 size_t num_tokens = 0;
139 char **new_tokens;
140 size_t new_max_tokens;
141 char *buffer;
142 int ret = 0;
143 char *token = 0;
144
145 if (!(buffer = jas_strdup(string))) {
146 ret = -1;
147 goto done;
148 }
149 //new_max_tokens = 1;
150 new_max_tokens = 0;
151 if (new_max_tokens > 0) {
152 if (!(tokens = jas_malloc(new_max_tokens * sizeof(char *)))) {
153 ret = -1;
154 goto done;
155 }
156 max_tokens = new_max_tokens;
157 }
158
159 bool first = true;
160 char *saveptr = 0;
161 for (;;) {
162 char *cp;
163 if (!(cp = jas_strtok(first ? buffer : 0, delim, &saveptr))) {
164 break;
165 }
166 first = false;
167 if (!(token = jas_strdup(cp))) {
168 ret = -1;
169 goto done;
170 }
171 if (num_tokens == max_tokens) {
172 new_max_tokens = max_tokens ? 2 * max_tokens : 1;
173 if (!(new_tokens = jas_realloc(tokens, new_max_tokens *
174 sizeof(char *)))) {
175 ret = -1;
176 goto done;
177 }
178 tokens = new_tokens;
179 max_tokens = new_max_tokens;
180 }
181 assert(num_tokens < max_tokens);
182 tokens[num_tokens] = token;
183 token = 0;
184 ++num_tokens;
185 }
186
187done:
188 if (buffer) {
189 jas_free(buffer);
190 }
191 if (ret && tokens) {
192 for (int i = 0; i < num_tokens; ++i) {
193 jas_free(tokens[i]);
194 }
195 jas_free(tokens);
196 tokens = 0;
197 max_tokens = 0;
198 num_tokens = 0;
199 }
200 if (token) {
201 jas_free(token);
202 }
203 if (!ret) {
204 *tokens_buf = tokens;
205 *max_tokens_buf = max_tokens;
206 *num_tokens_buf = num_tokens;
207 }
208 if (jas_get_debug_level() >= 100) {
209 jas_eprintf("tokens %p; max_tokens %zu; num_tokens %zu\n",
210 JAS_CAST(void *, tokens), max_tokens, num_tokens);
211 for (int i = 0; i < num_tokens; ++i) {
212 jas_eprintf("[%d] = %s\n", i, tokens[i]);
213 }
214 }
215 return ret;
216}
jas_tvp.c+234−0
@@ -0,0 +1,234 @@
1/*
2 * Copyright (c) 2001-2002 Michael David Adams.
3 * All rights reserved.
4 */
5
6/* __START_OF_JASPER_LICENSE__
7 *
8 * JasPer License Version 2.0
9 *
10 * Copyright (c) 2001-2006 Michael David Adams
11 * Copyright (c) 1999-2000 Image Power, Inc.
12 * Copyright (c) 1999-2000 The University of British Columbia
13 *
14 * All rights reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person (the
17 * "User") obtaining a copy of this software and associated documentation
18 * files (the "Software"), to deal in the Software without restriction,
19 * including without limitation the rights to use, copy, modify, merge,
20 * publish, distribute, and/or sell copies of the Software, and to permit
21 * persons to whom the Software is furnished to do so, subject to the
22 * following conditions:
23 *
24 * 1. The above copyright notices and this permission notice (which
25 * includes the disclaimer below) shall be included in all copies or
26 * substantial portions of the Software.
27 *
28 * 2. The name of a copyright holder shall not be used to endorse or
29 * promote products derived from the Software without specific prior
30 * written permission.
31 *
32 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
33 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
34 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
35 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
37 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
38 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
39 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
40 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
41 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
42 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
43 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
44 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
45 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
46 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
47 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
48 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
49 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
50 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
51 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
52 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
53 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
54 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
55 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
56 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
57 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
58 *
59 * __END_OF_JASPER_LICENSE__
60 */
61
62/*
63 * Tag-Value Parser Library
64 *
65 * $Id$
66 */
67
68/******************************************************************************\
69* Includes.
70\******************************************************************************/
71
72#define JAS_FOR_INTERNAL_USE_ONLY
73
74#include "jasper/jas_tvp.h"
75#include "jasper/jas_malloc.h"
76#include "jasper/jas_string.h"
77
78/******************************************************************************\
79* Macros.
80\******************************************************************************/
81
82/* Is the specified character valid for a tag name? */
83#define JAS_TVP_ISTAG(x) \
84 (isalpha(x) || (x) == '_' || isdigit(x))
85
86/******************************************************************************\
87* Code for creating and destroying a tag-value parser.
88\******************************************************************************/
89
90jas_tvparser_t *jas_tvparser_create(const char *s)
91{
92 jas_tvparser_t *tvp;
93 if (!(tvp = jas_malloc(sizeof(jas_tvparser_t)))) {
94 return 0;
95 }
96 if (!(tvp->buf = jas_strdup(s))) {
97 jas_tvparser_destroy(tvp);
98 return 0;
99 }
100 tvp->pos = tvp->buf;
101 tvp->tag = 0;
102 tvp->val = 0;
103 return tvp;
104}
105
106void jas_tvparser_destroy(jas_tvparser_t *tvp)
107{
108 if (tvp->buf) {
109 jas_free(tvp->buf);
110 }
111 jas_free(tvp);
112}
113
114/******************************************************************************\
115* Main parsing code.
116\******************************************************************************/
117
118/* Get the next tag-value pair. */
119int jas_tvparser_next(jas_tvparser_t *tvp)
120{
121 char *p;
122 char *tag;
123 char *val;
124
125 /* Skip any leading whitespace. */
126 p = tvp->pos;
127 while (*p != '\0' && isspace(JAS_CAST(unsigned char, *p))) {
128 ++p;
129 }
130
131 /* Has the end of the input data been reached? */
132 if (*p == '\0') {
133 /* No more tags are present. */
134 tvp->pos = p;
135 return 1;
136 }
137
138 /* Does the tag name begin with a valid character? */
139 if (!JAS_TVP_ISTAG(JAS_CAST(unsigned char, *p))) {
140 return -1;
141 }
142
143 /* Remember where the tag name begins. */
144 tag = p;
145
146 /* Find the end of the tag name. */
147 while (*p != '\0' && JAS_TVP_ISTAG(JAS_CAST(unsigned char, *p))) {
148 ++p;
149 }
150
151 /* Has the end of the input data been reached? */
152 if (*p == '\0') {
153 /* The value field is empty. */
154 tvp->tag = tag;
155 tvp->val = "";
156 tvp->pos = p;
157 return 0;
158 }
159
160 /* Is a value field not present? */
161 if (*p != '=') {
162 if (*p != '\0' && !isspace(JAS_CAST(unsigned char, *p))) {
163 return -1;
164 }
165 *p++ = '\0';
166 tvp->tag = tag;
167 tvp->val = "";
168 tvp->pos = p;
169 return 0;
170 }
171
172 *p++ = '\0';
173
174 val = p;
175 while (*p != '\0' && !isspace(JAS_CAST(unsigned char, *p))) {
176 ++p;
177 }
178
179 if (*p != '\0') {
180 *p++ = '\0';
181 }
182
183 tvp->pos = p;
184 tvp->tag = tag;
185 tvp->val = val;
186
187 return 0;
188}
189
190/******************************************************************************\
191* Code for querying the current tag/value.
192\******************************************************************************/
193
194/* Get the current tag. */
195const char *jas_tvparser_gettag(const jas_tvparser_t *tvp)
196{
197 return tvp->tag;
198}
199
200/* Get the current value. */
201const char *jas_tvparser_getval(const jas_tvparser_t *tvp)
202{
203 return tvp->val;
204}
205
206/******************************************************************************\
207* Miscellaneous code.
208\******************************************************************************/
209
210/* Lookup a tag by name. */
211const jas_taginfo_t *jas_taginfos_lookup(const jas_taginfo_t *taginfos, const char *name)
212{
213 const jas_taginfo_t *taginfo;
214 taginfo = taginfos;
215 while (taginfo->id >= 0) {
216 if (!strcmp(taginfo->name, name)) {
217 return taginfo;
218 }
219 ++taginfo;
220 }
221 return 0;
222}
223
224/* This function is simply for convenience. */
225/* One can avoid testing for the special case of a null pointer, by
226 using this function. This function never returns a null pointer. */
227const jas_taginfo_t *jas_taginfo_nonull(const jas_taginfo_t *taginfo)
228{
229 static const jas_taginfo_t invalidtaginfo = {
230 -1, 0
231 };
232
233 return taginfo ? taginfo : &invalidtaginfo;
234}
jas_version.c+69−0
@@ -0,0 +1,69 @@
1/*
2 * Copyright (c) 2001-2002 Michael David Adams.
3 * All rights reserved.
4 */
5
6/* __START_OF_JASPER_LICENSE__
7 *
8 * JasPer License Version 2.0
9 *
10 * Copyright (c) 2001-2006 Michael David Adams
11 * Copyright (c) 1999-2000 Image Power, Inc.
12 * Copyright (c) 1999-2000 The University of British Columbia
13 *
14 * All rights reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person (the
17 * "User") obtaining a copy of this software and associated documentation
18 * files (the "Software"), to deal in the Software without restriction,
19 * including without limitation the rights to use, copy, modify, merge,
20 * publish, distribute, and/or sell copies of the Software, and to permit
21 * persons to whom the Software is furnished to do so, subject to the
22 * following conditions:
23 *
24 * 1. The above copyright notices and this permission notice (which
25 * includes the disclaimer below) shall be included in all copies or
26 * substantial portions of the Software.
27 *
28 * 2. The name of a copyright holder shall not be used to endorse or
29 * promote products derived from the Software without specific prior
30 * written permission.
31 *
32 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
33 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
34 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
35 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
37 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
38 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
39 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
40 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
41 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
42 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
43 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
44 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
45 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
46 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
47 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
48 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
49 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
50 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
51 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
52 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
53 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
54 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
55 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
56 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
57 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
58 *
59 * __END_OF_JASPER_LICENSE__
60 */
61
62#define JAS_FOR_INTERNAL_USE_ONLY
63
64#include "jasper/jas_version.h"
65
66const char *jas_getversion()
67{
68 return JAS_VERSION;
69}
jasper/jas_cm.h+249−21
@@ -67,18 +67,39 @@ · 66 unmodified lines
67#ifndef JAS_CM_H67#ifndef JAS_CM_H
68#define JAS_CM_H68#define JAS_CM_H
69 69
70/******************************************************************************\
71*
72\******************************************************************************/
73
70/* The configuration header file should be included first. */74/* The configuration header file should be included first. */
71#include <jasper/jas_config.h>75#include <jasper/jas_config.h>
72 76
77#include <jasper/jas_types.h>
73#include <jasper/jas_icc.h>78#include <jasper/jas_icc.h>
74 79
75#ifdef __cplusplus80#ifdef __cplusplus
76extern "C" {81extern "C" {
77#endif82#endif
78 83
84/*!
85 * @addtogroup module_cm
86 * @{
87 */
88
89/******************************************************************************\
90* Types and Macros.
91\******************************************************************************/
92
93/*!
94@brief
95Color space.
96*/
79typedef unsigned jas_clrspc_t;97typedef unsigned jas_clrspc_t;
80 98
81/* transform operations */99/*!
100@brief
101Transform operations
102*/
82typedef enum {103typedef enum {
83 JAS_CMXFORM_OP_FWD = 0,104 JAS_CMXFORM_OP_FWD = 0,
84 JAS_CMXFORM_OP_REV = 1,105 JAS_CMXFORM_OP_REV = 1,
@@ -86,7 +107,10 @@ typedef enum { · 1 unmodified line
86 JAS_CMXFORM_OP_GAMUT = 3,107 JAS_CMXFORM_OP_GAMUT = 3,
87} jas_cmxform_op_t;108} jas_cmxform_op_t;
88 109
89/* rendering intents */110/*!
111@brief
112Rendering intents.
113*/
90typedef enum {114typedef enum {
91 JAS_CMXFORM_INTENT_PER = 0,115 JAS_CMXFORM_INTENT_PER = 0,
92 JAS_CMXFORM_INTENT_RELCLR = 1,116 JAS_CMXFORM_INTENT_RELCLR = 1,
@@ -94,24 +118,58 @@ typedef enum { · 1 unmodified line
94 JAS_CMXFORM_INTENT_SAT = 3,118 JAS_CMXFORM_INTENT_SAT = 3,
95} jas_cmxform_intent_t;119} jas_cmxform_intent_t;
96 120
121/*!
122@brief
123Number of rendering intents.
124*/
97#define JAS_CMXFORM_NUMINTENTS 4125#define JAS_CMXFORM_NUMINTENTS 4
98 126
127/*!
128@brief
129Transform optimization.
130*/
99typedef enum {131typedef enum {
100 JAS_CMXFORM_OPTM_SPEED = 0,132 JAS_CMXFORM_OPTM_SPEED = 0,
101 JAS_CMXFORM_OPTM_SIZE = 1,133 JAS_CMXFORM_OPTM_SIZE = 1,
102 JAS_CMXFORM_OPTM_ACC = 2,134 JAS_CMXFORM_OPTM_ACC = 2,
103} jas_cmxform_optm_t;135} jas_cmxform_optm_t;
104 136
105 137/*!
138@brief
139Create a color space.
140*/
106#define jas_clrspc_create(fam, mbr) (((fam) << 8) | (mbr))141#define jas_clrspc_create(fam, mbr) (((fam) << 8) | (mbr))
142
143/*!
144@brief
145Get the family of a color space.
146*/
147
107#define jas_clrspc_fam(clrspc) ((clrspc) >> 8)148#define jas_clrspc_fam(clrspc) ((clrspc) >> 8)
149
150/*!
151@brief
152Get the (family) member of a color space.
153*/
108#define jas_clrspc_mbr(clrspc) ((clrspc) & 0xff)154#define jas_clrspc_mbr(clrspc) ((clrspc) & 0xff)
155
156/*!
157@brief
158Test if a color space is generic.
159*/
109#define jas_clrspc_isgeneric(clrspc) (!jas_clrspc_mbr(clrspc))160#define jas_clrspc_isgeneric(clrspc) (!jas_clrspc_mbr(clrspc))
161
162/*!
163@brief
164Test if a color space is unknown.
165*/
110#define jas_clrspc_isunknown(clrspc) ((clrspc) & JAS_CLRSPC_UNKNOWNMASK)166#define jas_clrspc_isunknown(clrspc) ((clrspc) & JAS_CLRSPC_UNKNOWNMASK)
111 167
112#define JAS_CLRSPC_UNKNOWNMASK 0x4000168#define JAS_CLRSPC_UNKNOWNMASK 0x4000
113 169
114/* color space families */170/*!
171@brief Color space families.
172*/
115#define JAS_CLRSPC_FAM_UNKNOWN 0173#define JAS_CLRSPC_FAM_UNKNOWN 0
116#define JAS_CLRSPC_FAM_XYZ 1174#define JAS_CLRSPC_FAM_XYZ 1
117#define JAS_CLRSPC_FAM_LAB 2175#define JAS_CLRSPC_FAM_LAB 2
@@ -119,7 +177,9 @@ typedef enum { · 1 unmodified line
119#define JAS_CLRSPC_FAM_RGB 4177#define JAS_CLRSPC_FAM_RGB 4
120#define JAS_CLRSPC_FAM_YCBCR 5178#define JAS_CLRSPC_FAM_YCBCR 5
121 179
122/* specific color spaces */180/*!
181@brief Specific color spaces.
182*/
123#define JAS_CLRSPC_UNKNOWN JAS_CLRSPC_UNKNOWNMASK183#define JAS_CLRSPC_UNKNOWN JAS_CLRSPC_UNKNOWNMASK
124#define JAS_CLRSPC_CIEXYZ jas_clrspc_create(JAS_CLRSPC_FAM_XYZ, 1)184#define JAS_CLRSPC_CIEXYZ jas_clrspc_create(JAS_CLRSPC_FAM_XYZ, 1)
125#define JAS_CLRSPC_CIELAB jas_clrspc_create(JAS_CLRSPC_FAM_LAB, 1)185#define JAS_CLRSPC_CIELAB jas_clrspc_create(JAS_CLRSPC_FAM_LAB, 1)
@@ -127,7 +187,9 @@ typedef enum { · 1 unmodified line
127#define JAS_CLRSPC_SRGB jas_clrspc_create(JAS_CLRSPC_FAM_RGB, 1)187#define JAS_CLRSPC_SRGB jas_clrspc_create(JAS_CLRSPC_FAM_RGB, 1)
128#define JAS_CLRSPC_SYCBCR jas_clrspc_create(JAS_CLRSPC_FAM_YCBCR, 1)188#define JAS_CLRSPC_SYCBCR jas_clrspc_create(JAS_CLRSPC_FAM_YCBCR, 1)
129 189
130/* generic color spaces */190/*!
191@brief Generic color spaces.
192*/
131#define JAS_CLRSPC_GENRGB jas_clrspc_create(JAS_CLRSPC_FAM_RGB, 0)193#define JAS_CLRSPC_GENRGB jas_clrspc_create(JAS_CLRSPC_FAM_RGB, 0)
132#define JAS_CLRSPC_GENGRAY jas_clrspc_create(JAS_CLRSPC_FAM_GRAY, 0)194#define JAS_CLRSPC_GENGRAY jas_clrspc_create(JAS_CLRSPC_FAM_GRAY, 0)
133#define JAS_CLRSPC_GENYCBCR jas_clrspc_create(JAS_CLRSPC_FAM_YCBCR, 0)195#define JAS_CLRSPC_GENYCBCR jas_clrspc_create(JAS_CLRSPC_FAM_YCBCR, 0)
@@ -142,10 +204,17 @@ typedef enum { · 8 unmodified lines
142 204
143#define JAS_CLRSPC_CHANIND_GRAY_Y 0205#define JAS_CLRSPC_CHANIND_GRAY_Y 0
144 206
207/*!
208Real-number type.
209*/
145typedef double jas_cmreal_t;210typedef double jas_cmreal_t;
146 211
147struct jas_cmpxform_s;212struct jas_cmpxform_s;
148 213
214/*!
215@brief
216Component format.
217*/
149typedef struct {218typedef struct {
150 long *buf;219 long *buf;
151 unsigned prec;220 unsigned prec;
@@ -154,21 +223,38 @@ typedef struct { · 2 unmodified lines
154 unsigned height;223 unsigned height;
155} jas_cmcmptfmt_t;224} jas_cmcmptfmt_t;
156 225
226/*!
227@brief
228Pixmap (i.e., multicomponent) format.
229*/
157typedef struct {230typedef struct {
158 unsigned numcmpts;231 unsigned numcmpts;
159 jas_cmcmptfmt_t *cmptfmts;232 jas_cmcmptfmt_t *cmptfmts;
160} jas_cmpixmap_t;233} jas_cmpixmap_t;
161 234
235/*!
236@brief
237Transform operations.
238*/
162typedef struct {239typedef struct {
163 void (*destroy)(struct jas_cmpxform_s *pxform);240 void (*destroy)(struct jas_cmpxform_s *pxform);
164 int (*apply)(const struct jas_cmpxform_s *pxform, const jas_cmreal_t *in, jas_cmreal_t *out, unsigned cnt);241 int (*apply)(const struct jas_cmpxform_s *pxform, const jas_cmreal_t *in, jas_cmreal_t *out, unsigned cnt);
242 void (*dump)(struct jas_cmpxform_s *pxform);
165} jas_cmpxformops_t;243} jas_cmpxformops_t;
166 244
245/*!
246@brief
247Shaper matrix look-up table (LUT).
248*/
167typedef struct {249typedef struct {
168 jas_cmreal_t *data;250 jas_cmreal_t *data;
169 unsigned size;251 unsigned size;
170} jas_cmshapmatlut_t;252} jas_cmshapmatlut_t;
171 253
254/*!
255@brief
256Shaper matrix.
257*/
172typedef struct {258typedef struct {
173 int mono;259 int mono;
174 int order;260 int order;
@@ -178,36 +264,54 @@ typedef struct { · 3 unmodified lines
178 jas_cmreal_t mat[3][4];264 jas_cmreal_t mat[3][4];
179} jas_cmshapmat_t;265} jas_cmshapmat_t;
180 266
267/*!
268@brief
269Shaper look-up table (LUT).
270*/
181typedef struct {271typedef struct {
182 int order;272 int order;
183} jas_cmshaplut_t;273} jas_cmshaplut_t;
184 274
275/*!
276@brief
277Color space conversion.
278*/
185typedef struct {279typedef struct {
186 unsigned inclrspc;280 unsigned inclrspc;
187 unsigned outclrspc;281 unsigned outclrspc;
188} jas_cmclrspcconv_t;282} jas_cmclrspcconv_t;
189 283
190#define jas_align_t double284/*!
191 285@brief
286Transform class.
287*/
192typedef struct jas_cmpxform_s {288typedef struct jas_cmpxform_s {
193 unsigned refcnt;289 unsigned refcnt;
194 const jas_cmpxformops_t *ops;290 const jas_cmpxformops_t *ops;
195 unsigned numinchans;291 unsigned numinchans;
196 unsigned numoutchans;292 unsigned numoutchans;
197 union {293 union {
198 jas_align_t dummy;294 max_align_t dummy;
199 jas_cmshapmat_t shapmat;295 jas_cmshapmat_t shapmat;
200 jas_cmshaplut_t shaplut;296 jas_cmshaplut_t shaplut;
201 jas_cmclrspcconv_t clrspcconv;297 jas_cmclrspcconv_t clrspcconv;
202 } data;298 } data;
203} jas_cmpxform_t;299} jas_cmpxform_t;
204 300
301/*!
302@brief
303Primitive transform sequence class.
304*/
205typedef struct {305typedef struct {
206 unsigned numpxforms;306 unsigned numpxforms;
207 unsigned maxpxforms;307 unsigned maxpxforms;
208 jas_cmpxform_t **pxforms;308 jas_cmpxform_t **pxforms;
209} jas_cmpxformseq_t;309} jas_cmpxformseq_t;
210 310
311/*!
312@brief
313Primitive transform class.
314*/
211typedef struct {315typedef struct {
212 unsigned numinchans;316 unsigned numinchans;
213 unsigned numoutchans;317 unsigned numoutchans;
@@ -219,6 +323,9 @@ typedef struct { · 5 unmodified lines
219 323
220#define JAS_CMPROF_NUMPXFORMSEQS 13324#define JAS_CMPROF_NUMPXFORMSEQS 13
221 325
326/*!
327Color-management (CM) profile.
328*/
222typedef struct {329typedef struct {
223 jas_clrspc_t clrspc;330 jas_clrspc_t clrspc;
224 unsigned numchans;331 unsigned numchans;
@@ -228,6 +335,10 @@ typedef struct { · 3 unmodified lines
228 jas_cmpxformseq_t *pxformseqs[JAS_CMPROF_NUMPXFORMSEQS];335 jas_cmpxformseq_t *pxformseqs[JAS_CMPROF_NUMPXFORMSEQS];
229} jas_cmprof_t;336} jas_cmprof_t;
230 337
338/******************************************************************************\
339*
340\******************************************************************************/
341
231#if 0342#if 0
232typedef int_fast32_t jas_cmattrname_t;343typedef int_fast32_t jas_cmattrname_t;
233typedef int_fast32_t jas_cmattrval_t;344typedef int_fast32_t jas_cmattrval_t;
@@ -242,27 +353,144 @@ int jas_cm_prof_setattr(jas_cm_prof_t *prof, jas_cm_attrname_t name, void *val); · 8 unmodified lines
242void *jas_cm_prof_getattr(jas_cm_prof_t *prof, jas_cm_attrname_t name);353void *jas_cm_prof_getattr(jas_cm_prof_t *prof, jas_cm_attrname_t name);
243#endif354#endif
244 355
245JAS_DLLEXPORT jas_cmxform_t *jas_cmxform_create(const jas_cmprof_t *inprof, const jas_cmprof_t *outprof,356/******************************************************************************\
246 const jas_cmprof_t *proofprof, jas_cmxform_op_t op, jas_cmxform_intent_t intent, jas_cmxform_optm_t optimize);357* Color-management (CM) profile class.
358\******************************************************************************/
247 359
248JAS_DLLEXPORT void jas_cmxform_destroy(jas_cmxform_t *xform);360/*!
361@brief
362Create a color-management profile from an ICC profile.
363
364@details
365This function creates a CM profile from an ICC profile.
366
367@returns
368If successful, a pointer to the created CM profile is returned.
369Otherwise, a null pointer is returned.
370*/
371JAS_EXPORT
372jas_cmprof_t *jas_cmprof_createfromiccprof(const jas_iccprof_t *iccprof);
373
374/*!
375@brief
376Create a color-management profile from a color space.
377
378@details
379The function creates a CM profile from a color space.
380
381@returns
382If successful, a pointer to the created CM profile is returned.
383Otherwise, a null pointer is returned.
384*/
385JAS_EXPORT
386jas_cmprof_t *jas_cmprof_createfromclrspc(jas_clrspc_t clrspc);
387
388/*!
389@brief Destroy a color-management profile.
390
391@details
392*/
393JAS_EXPORT
394void jas_cmprof_destroy(jas_cmprof_t *prof);
395
396/*!
397@brief
398Copy a color-management profile.
399
400@details
401This function creates a clone (i.e., copy) of a CM profile.
402
403@returns
404If successful, a pointer to the newly created CM profile is returned.
405Otherwise, a null pointer is returned.
406*/
407JAS_EXPORT
408jas_cmprof_t *jas_cmprof_copy(const jas_cmprof_t *prof);
409
410/*!
411@brief
412Create a ICC profile from a CM profile.
413
414@details
415This function creates an ICC profile from a CM profile.
416
417@returns
418If successful, a pointer to the created ICC profile is returned.
419Otherwise, a null pointer is returned.
420*/
421JAS_EXPORT
422jas_iccprof_t *jas_iccprof_createfromcmprof(const jas_cmprof_t *prof);
423
424/******************************************************************************\
425* Color-Management (CM) Transform.
426\******************************************************************************/
249 427
250/* Apply a transform to data. */428/*!
251JAS_DLLEXPORT int jas_cmxform_apply(const jas_cmxform_t *xform, const jas_cmpixmap_t *in,429@brief
430Create a transform from a CM profile.
431
432@details
433
434@returns
435If successful, a pointer to the created transform is returned.
436Otherwise, a null pointer is returned.
437*/
438JAS_EXPORT
439jas_cmxform_t *jas_cmxform_create(const jas_cmprof_t *inprof,
440 const jas_cmprof_t *outprof, const jas_cmprof_t *proofprof,
441 jas_cmxform_op_t op, jas_cmxform_intent_t intent,
442 jas_cmxform_optm_t optimize);
443
444/*!
445@brief
446Destroy a transform.
447
448@details
449*/
450JAS_EXPORT
451void jas_cmxform_destroy(jas_cmxform_t *xform);
452
453/*!
454@brief
455Apply a transform to data.
456
457@details
458
459@returns
460If successful, zero is returned.
461Otherwise, a nonzero value is returned.
462*/
463JAS_EXPORT
464int jas_cmxform_apply(const jas_cmxform_t *xform, const jas_cmpixmap_t *in,
252 jas_cmpixmap_t *out);465 jas_cmpixmap_t *out);
253 466
254/* Create a profile. */467/******************************************************************************\
255JAS_DLLEXPORT jas_cmprof_t *jas_cmprof_createfromiccprof(const jas_iccprof_t *iccprof);468* Miscellany.
256JAS_DLLEXPORT jas_cmprof_t *jas_cmprof_createfromclrspc(jas_clrspc_t clrspc);469\******************************************************************************/
470
471/*!
472@brief
473Get the number of channels associated with a particular color space.
257 474
258/* Destroy a profile. */475@details
259JAS_DLLEXPORT void jas_cmprof_destroy(jas_cmprof_t *prof);
260 476
477@returns
478*/
261unsigned jas_clrspc_numchans(jas_clrspc_t clrspc);479unsigned jas_clrspc_numchans(jas_clrspc_t clrspc);
262JAS_DLLEXPORT jas_iccprof_t *jas_iccprof_createfromcmprof(const jas_cmprof_t *prof);
263 480
481/*!
482@brief
483Get the color space associated with a color-management profile.
484
485@details
486
487@returns
488*/
264#define jas_cmprof_clrspc(prof) ((prof)->clrspc)489#define jas_cmprof_clrspc(prof) ((prof)->clrspc)
265JAS_DLLEXPORT jas_cmprof_t *jas_cmprof_copy(const jas_cmprof_t *prof);490
491/*!
492 * @}
493 */
266 494
267#ifdef __cplusplus495#ifdef __cplusplus
268}496}
jasper/jas_compiler.h+69−25
@@ -66,38 +66,82 @@ · 65 unmodified lines
66#include <jasper/jas_config.h>66#include <jasper/jas_config.h>
67 67
68#ifdef _MSC_VER68#ifdef _MSC_VER
69#ifndef __cplusplus69# ifndef __cplusplus
70#undef inline70# undef inline
71#define inline __inline71# define inline __inline
72# endif
72#endif73#endif
74
75#if defined(__GNUC__)
76# define JAS_DEPRECATED __attribute__((deprecated))
77#else
78# define JAS_DEPRECATED
79#endif
80
81#if defined(__GNUC__)
82# define JAS_ATTRIBUTE_CONST __attribute__((const))
83#else
84# define JAS_ATTRIBUTE_CONST
85#endif
86
87#if defined(__GNUC__)
88# define JAS_ATTRIBUTE_PURE __attribute__((pure))
89#else
90# define JAS_ATTRIBUTE_PURE
91#endif
92
93#if defined(__GNUC__)
94# define JAS_FORCE_INLINE inline __attribute__((always_inline))
95#else
96# define JAS_FORCE_INLINE inline
73#endif97#endif
74 98
75#ifdef __GNUC__99#if defined(__GNUC__)
76#define JAS_DEPRECATED __attribute__((deprecated))100# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
77#define JAS_ATTRIBUTE_CONST __attribute__((const))101# define JAS_UNREACHABLE() __builtin_unreachable()
78#define JAS_ATTRIBUTE_PURE __attribute__((pure))102# else
79#define JAS_FORCE_INLINE inline __attribute__((always_inline))103# define JAS_UNREACHABLE()
80#define JAS_UNREACHABLE() __builtin_unreachable()104# endif
81#define JAS_LIKELY(x) __builtin_expect (!!(x), 1)105#elif defined(__clang__)
82#define JAS_UNLIKELY(x) __builtin_expect (!!(x), 0)106# define JAS_UNREACHABLE() __builtin_unreachable()
107#elif defined(_MSC_VER)
108# define JAS_UNREACHABLE() __assume(0)
83#else109#else
84#define JAS_DEPRECATED110# define JAS_UNREACHABLE()
85#define JAS_ATTRIBUTE_CONST
86#define JAS_ATTRIBUTE_PURE
87#define JAS_FORCE_INLINE inline
88#define JAS_UNREACHABLE()
89#define JAS_LIKELY(x) (x)
90#define JAS_UNLIKELY(x) (x)
91#endif111#endif
92 112
93#ifdef __clang__113#if defined(__GNUC__)
94#define JAS_ATTRIBUTE_DISABLE_USAN \114# define JAS_LIKELY(x) __builtin_expect (!!(x), 1)
95 __attribute__((no_sanitize("undefined")))
96#elif defined(__GNUC__) && __GNUC__ >= 6
97#define JAS_ATTRIBUTE_DISABLE_USAN \
98 __attribute__((no_sanitize_undefined))
99#else115#else
100#define JAS_ATTRIBUTE_DISABLE_USAN116# define JAS_LIKELY(x) (x)
101#endif117#endif
102 118
119#if defined(__GNUC__)
120# define JAS_UNLIKELY(x) __builtin_expect (!!(x), 0)
121#else
122# define JAS_UNLIKELY(x) (x)
123#endif
124
125#if defined(__GNUC__) && __GNUC__ >= 6
126# define JAS_ATTRIBUTE_DISABLE_UBSAN \
127 __attribute__((no_sanitize_undefined))
128#elif defined(__clang__)
129# define JAS_ATTRIBUTE_DISABLE_UBSAN \
130 __attribute__((no_sanitize("undefined")))
131#else
132# define JAS_ATTRIBUTE_DISABLE_UBSAN
133#endif
134
135#ifdef __has_builtin
136#define jas_has_builtin(x) __has_builtin(x)
137#else
138#define jas_has_builtin(x) 0
139#endif
140
141/*!
142@brief
143Indicate that a variable may be unused (in order to avoid a compiler warning).
144*/
145#define JAS_UNUSED(x) USED(x)
146
103#endif147#endif
jasper/jas_config.h+73−3
@@ -4,17 +4,87 @@ · 3 unmodified lines
4#include <u.h>4#include <u.h>
5#include <libc.h>5#include <libc.h>
6#include <ctype.h>6#include <ctype.h>
7#include <stdio.h>
8
9#define bool int
10#define false 0
11#define true 1
12
13#define PRIxFAST32 "x"
14#define PRIxFAST16 PRIxFAST32
15#define PRIuFAST32 "ud"
16#define PRIuFAST16 PRIuFAST32
17#define PRIiFAST32 "d"
18#define PRIdPTR "p"
19
20#define PRIuLEAST32 PRIuFAST32
21#define PRIiLEAST32 PRIiFAST32
22#define PRIxLEAST32 PRIxFAST32
23#define PRIxLEAST16 PRIxFAST16
24
25typedef u8int uint_least8_t;
26typedef s8int int_least8_t;
27typedef u16int uint_least16_t;
28typedef s16int int_least16_t;
29typedef u32int uint_least32_t;
30typedef s32int int_least32_t;
31typedef u64int uint_least64_t;
32
33typedef u8int uint_fast8_t;
34typedef u16int uint_fast16_t;
35typedef s16int int_fast16_t;
36typedef u32int uint_fast32_t;
37typedef s32int int_fast32_t;
38typedef u64int uint_fast64_t;
39typedef s64int int_least64_t;
40
41// FIXME
42typedef s64int intmax_t;
43typedef long ssize_t;
44typedef ulong size_t;
45
46#define SIZE_MAX 0xffffffffU
47#define LONG_MAX 0x7fffffffL
48#define INT_FAST32_MAX 0x7fffffff
49#define INT_FAST32_MIN (-INT_FAST32_MAX-1)
50#define UINT_FAST32_MAX 0xffffffffU
51#define INT_LEAST64_MAX 0x7fffffffffffffff
52#define INT_LEAST64_MIN ((s64int)0x8000000000000000ULL)
53#define UINT_LEAST64_MAX 0xffffffffffffffffULL
54
55#define INT_LEAST32_MIN INT_FAST32_MIN
56#define INT_LEAST32_MAX INT_FAST32_MAX
57#define UINT_LEAST32_MAX UINT_FAST32_MAX
58#define INT_MAX INT_FAST32_MAX
59
60#define DBL_MAX 1.7976931348623157E+308
61
62#define O_RDWR ORDWR
63#define O_RDONLY OREAD
64#define O_WRONLY OWRITE
65#define O_BINARY 0
66#define O_TRUNC OTRUNC
67#define O_CLOEXEC OCEXEC
68
69// FIXME
70#define O_APPEND 0
71#define O_CREAT 0
72
7#include <jasper/jas_compiler.h>73#include <jasper/jas_compiler.h>
8#include <jasper/jas_dll.h>74#include <jasper/jas_dll.h>
9 75
10#define JAS_VERSION "plan9"76#define JAS_VERSION "plan9"
77#define JAS_DEFAULT_MAX_MEM_USAGE (512*1024*1024)
11#define JAS_ENABLE_32BIT 178#define JAS_ENABLE_32BIT 1
12#define JAS_INCLUDE_JP2_CODEC 179#define JAS_ENABLE_JPC_CODEC 1
80#define JAS_ENABLE_JP2_CODEC 1
13#define JAS_INCLUDE_JPC_CODEC 181#define JAS_INCLUDE_JPC_CODEC 1
82#define JAS_INCLUDE_JP2_CODEC 1
14#define JAS_DEC_DEFAULT_MAX_SAMPLES (64 * ((size_t) 1048576))83#define JAS_DEC_DEFAULT_MAX_SAMPLES (64 * ((size_t) 1048576))
15#define NDEBUG84#define NDEBUG
16#define NULL nil85#define JAS_EXPORT
17 86
18typedef usize size_t;87#define unlink remove
88#define lseek seek
19 89
20#endif90#endif
jasper/jas_debug.h+100−10
@@ -74,6 +74,9 @@ · 73 unmodified lines
74/* The configuration header file should be included first. */74/* The configuration header file should be included first. */
75#include <jasper/jas_config.h>75#include <jasper/jas_config.h>
76 76
77#include "jasper/jas_init.h"
78#include "jasper/jas_debug.h"
79
77#ifdef __cplusplus80#ifdef __cplusplus
78extern "C" {81extern "C" {
79#endif82#endif
@@ -86,25 +89,112 @@ extern "C" { · 6 unmodified lines
86 level is set sufficiently high. */89 level is set sufficiently high. */
87#if !defined(NDEBUG)90#if !defined(NDEBUG)
88#define JAS_DBGLOG(n, x) \91#define JAS_DBGLOG(n, x) \
89 ((jas_getdbglevel() >= (n)) ? (jas_eprintf x) : 0)92 ((jas_get_debug_level() >= (n)) ? (jas_eprintf x) : 0)
90#else93#else
91#define JAS_DBGLOG(n, x)94#define JAS_DBGLOG(n, x)
92#endif95#endif
93 96
94/* Get the library debug level. */97#if !defined(NDEBUG)
95JAS_ATTRIBUTE_CONST98#define JAS_LOGDEBUGF(n, ...) \
96JAS_DLLEXPORT int jas_getdbglevel(void);99 ((jas_get_debug_level() >= (n)) ? jas_logdebugf((n), __VA_ARGS__) : 0)
100#else
101#define JAS_LOGDEBUGF(n, ...)
102#endif
103
104/*!
105@brief
106Warn about the use of deprecated functionality.
107*/
108JAS_EXPORT
109void jas_deprecated(const char *fmt, ...);
110
111/*!
112@brief
113Get the library debug level.
114
115@deprecated
116This function is deprecated.
117*/
118JAS_DEPRECATED
119static inline
120int jas_getdbglevel(void)
121{
122 jas_deprecated("jas_getdbglevel is deprecated\n");
123 return jas_get_debug_level();
124}
125
126/*!
127@brief
128Set the library debug level.
129*/
130JAS_EXPORT
131int jas_setdbglevel(int dbglevel);
132
133/*!
134@brief
135Print formatted text for the standard error stream (i.e., stderr).
136*/
137JAS_EXPORT
138int jas_eprintf(const char *fmt, ...);
139
140/*!
141@brief
142Generate a generic log message.
143*/
144JAS_EXPORT
145int jas_logprintf(const char *fmt, ...);
146
147/*!
148@brief
149Generate an error log message.
150*/
151JAS_EXPORT
152int jas_logerrorf(const char *fmt, ...);
153
154/*!
155@brief
156Generate a warning log message.
157*/
158JAS_EXPORT
159int jas_logwarnf(const char *fmt, ...);
160
161/*!
162@brief
163Generate an informational log message.
164*/
165JAS_EXPORT
166int jas_loginfof(const char *fmt, ...);
97 167
98/* Set the library debug level. */168/*!
99JAS_DLLEXPORT int jas_setdbglevel(int dbglevel);169@brief
170Generate a debugging log message.
171*/
172JAS_EXPORT
173int jas_logdebugf(int priority, const char *fmt, ...);
100 174
101/* Perform formatted output to standard error. */175/*!
102JAS_DLLEXPORT int jas_eprintf(const char *fmt, ...);176@brief
177Dump memory.
178*/
179int jas_logmemdump(const void *data, size_t len);
103 180
104/* Convert to a string literal */181/*!
182@brief
183Dump memory to a stream.
184*/
185JAS_EXPORT
186int jas_memdump(FILE *out, const void *data, size_t len);
187
188/*!
189@brief
190Convert to a string literal.
191*/
105#define JAS_STRINGIFY(x) #x192#define JAS_STRINGIFY(x) #x
106 193
107/* Convert to a string literal after macro expansion */194/*!
195@brief
196Convert to a string literal after macro expansion.
197*/
108#define JAS_STRINGIFYX(x) JAS_STRINGIFY(x)198#define JAS_STRINGIFYX(x) JAS_STRINGIFY(x)
109 199
110#ifdef __cplusplus200#ifdef __cplusplus
jasper/jas_dll.h+4−24
@@ -65,29 +65,9 @@ · 64 unmodified lines
65/* The configuration header file should be included first. */65/* The configuration header file should be included first. */
66#include <jasper/jas_config.h>66#include <jasper/jas_config.h>
67 67
68#if defined(JAS_DLL)68/* For backward compatibility only. */
69 #if defined(_WIN32)69#define JAS_DLLEXPORT JAS_EXPORT
70 #if defined(JAS_BUILDING_DLL)70/* For backward compatibility only. */
71 #define JAS_DLLEXPORT __declspec(dllexport)71#define JAS_DLLLOCAL JAS_LOCAL
72 #else
73 #define JAS_DLLEXPORT __declspec(dllimport)
74 #endif
75 #define JAS_DLLLOCAL
76 #elif defined(JAS_HAVE_VISIBILITY)
77 #if defined(JAS_BUILDING_DLL)
78 #define JAS_DLLEXPORT __attribute__ ((visibility("default")))
79 #define JAS_DLLLOCAL __attribute__ ((visibility("hidden")))
80 #else
81 #define JAS_DLLEXPORT
82 #define JAS_DLLLOCAL
83 #endif
84 #else
85 #define JAS_DLLEXPORT
86 #define JAS_DLLLOCAL
87 #endif
88#else
89 #define JAS_DLLEXPORT
90 #define JAS_DLLLOCAL
91#endif
92 72
93#endif73#endif
jasper/jas_fix.h+97−44
@@ -82,19 +82,52 @@ · 81 unmodified lines
82extern "C" {82extern "C" {
83#endif83#endif
84 84
85/*!
86 * @addtogroup module_fixed
87 * @{
88 */
89
90/******************************************************************************\
91* Types.
92\******************************************************************************/
93
94/*!
95Integral type used for fixed-point representations.
96*/
97#if defined(JAS_ENABLE_32BIT)
98typedef int_least32_t jas_fix_t;
99#define PRIjas_fix PRIiLEAST32
100#else
101typedef int_least64_t jas_fix_t;
102#define PRIjas_fix PRIiLEAST64
103#endif
104
105/*
106Integral type used for double-precision fixed-point representations.
107*/
108#if defined(JAS_ENABLE_32BIT)
109typedef int_least64_t jas_fix_big_t;
110#else
111#if defined(JAS_HAVE_INT128_T)
112typedef __int128_t jas_fix_big_t;
113#else
114typedef int_least64_t jas_fix_big_t;
115#endif
116#endif
117
85/******************************************************************************\118/******************************************************************************\
86* Constants.119* Constants.
87\******************************************************************************/120\******************************************************************************/
88 121
89/* The representation of the value zero. */122/*! The representation of the value zero. */
90#define JAS_FIX_ZERO(fix_t, fracbits) \123#define JAS_FIX_ZERO(fix_t, fracbits) \
91 JAS_INTTOFIX(fix_t, fracbits, 0)124 JAS_INTTOFIX(fix_t, fracbits, 0)
92 125
93/* The representation of the value one. */126/*! The representation of the value one. */
94#define JAS_FIX_ONE(fix_t, fracbits) \127#define JAS_FIX_ONE(fix_t, fracbits) \
95 JAS_INTTOFIX(fix_t, fracbits, 1)128 JAS_INTTOFIX(fix_t, fracbits, 1)
96 129
97/* The representation of the value one half. */130/*! The representation of the value one half. */
98#define JAS_FIX_HALF(fix_t, fracbits) \131#define JAS_FIX_HALF(fix_t, fracbits) \
99 (JAS_CAST(fix_t, 1) << ((fracbits) - 1))132 (JAS_CAST(fix_t, 1) << ((fracbits) - 1))
100 133
@@ -102,19 +135,19 @@ extern "C" { · 1 unmodified line
102* Conversion operations.135* Conversion operations.
103\******************************************************************************/136\******************************************************************************/
104 137
105/* Convert an int to a fixed-point number. */138/*! Convert an int to a fixed-point number. */
106#define JAS_INTTOFIX(fix_t, fracbits, x) \139#define JAS_INTTOFIX(fix_t, fracbits, x) \
107 (JAS_CAST(fix_t, x) << (fracbits))140 (JAS_CAST(fix_t, x) << (fracbits))
108 141
109/* Convert a fixed-point number to an int. */142/*! Convert a fixed-point number to an int. */
110#define JAS_FIXTOINT(fix_t, fracbits, x) \143#define JAS_FIXTOINT(fix_t, fracbits, x) \
111 JAS_CAST(int, (x) >> (fracbits))144 JAS_CAST(int, (x) >> (fracbits))
112 145
113/* Convert a fixed-point number to a double. */146/*! Convert a fixed-point number to a double. */
114#define JAS_FIXTODBL(fix_t, fracbits, x) \147#define JAS_FIXTODBL(fix_t, fracbits, x) \
115 (JAS_CAST(double, x) / JAS_FIX_ONE(fix_t, fracbits))148 (JAS_CAST(double, x) / JAS_FIX_ONE(fix_t, fracbits))
116 149
117/* Convert a double to a fixed-point number. */150/*! Convert a double to a fixed-point number. */
118#define JAS_DBLTOFIX(fix_t, fracbits, x) \151#define JAS_DBLTOFIX(fix_t, fracbits, x) \
119 JAS_CAST(fix_t, ((x) * JAS_CAST(double, JAS_FIX_ONE(fix_t, fracbits))))152 JAS_CAST(fix_t, ((x) * JAS_CAST(double, JAS_FIX_ONE(fix_t, fracbits))))
120 153
@@ -128,17 +161,17 @@ extern "C" { · 7 unmodified lines
128* Only the generic macros should be invoked directly by application code.161* Only the generic macros should be invoked directly by application code.
129\******************************************************************************/162\******************************************************************************/
130 163
131/* Calculate the sum of two fixed-point numbers. */164/*! Calculate the sum of two fixed-point numbers. */
132#if !defined(DEBUG_OVERFLOW)165#if !defined(DEBUG_OVERFLOW)
133#define JAS_FIX_ADD JAS_FIX_ADD_FAST166#define JAS_FIX_ADD JAS_FIX_ADD_FAST
134#else167#else
135#define JAS_FIX_ADD JAS_FIX_ADD_OFLOW168#define JAS_FIX_ADD JAS_FIX_ADD_OFLOW
136#endif169#endif
137 170
138/* Calculate the sum of two fixed-point numbers without overflow checking. */171/*! Calculate the sum of two fixed-point numbers without overflow checking. */
139#define JAS_FIX_ADD_FAST(fix_t, fracbits, x, y) ((x) + (y))172#define JAS_FIX_ADD_FAST(fix_t, fracbits, x, y) ((x) + (y))
140 173
141/* Calculate the sum of two fixed-point numbers with overflow checking. */174/*! Calculate the sum of two fixed-point numbers with overflow checking. */
142#define JAS_FIX_ADD_OFLOW(fix_t, fracbits, x, y) \175#define JAS_FIX_ADD_OFLOW(fix_t, fracbits, x, y) \
143 ((x) >= 0) ? \176 ((x) >= 0) ? \
144 (((y) >= 0) ? ((x) + (y) >= 0 || JAS_FIX_OFLOW(), (x) + (y)) : \177 (((y) >= 0) ? ((x) + (y) >= 0 || JAS_FIX_OFLOW(), (x) + (y)) : \
@@ -146,20 +179,20 @@ extern "C" { · 1 unmodified line
146 (((y) >= 0) ? ((x) + (y)) : ((x) + (y) < 0 || JAS_FIX_OFLOW(), \179 (((y) >= 0) ? ((x) + (y)) : ((x) + (y) < 0 || JAS_FIX_OFLOW(), \
147 (x) + (y)))180 (x) + (y)))
148 181
149/* Calculate the product of two fixed-point numbers. */182/*! Calculate the product of two fixed-point numbers. */
150#if !defined(DEBUG_OVERFLOW)183#if !defined(DEBUG_OVERFLOW)
151#define JAS_FIX_MUL JAS_FIX_MUL_FAST184#define JAS_FIX_MUL JAS_FIX_MUL_FAST
152#else185#else
153#define JAS_FIX_MUL JAS_FIX_MUL_OFLOW186#define JAS_FIX_MUL JAS_FIX_MUL_OFLOW
154#endif187#endif
155 188
156/* Calculate the product of two fixed-point numbers without overflow189/*! Calculate the product of two fixed-point numbers without overflow
157 checking. */190 checking. */
158#define JAS_FIX_MUL_FAST(fix_t, fracbits, bigfix_t, x, y) \191#define JAS_FIX_MUL_FAST(fix_t, fracbits, bigfix_t, x, y) \
159 JAS_CAST(fix_t, (JAS_CAST(bigfix_t, x) * JAS_CAST(bigfix_t, y)) >> \192 JAS_CAST(fix_t, (JAS_CAST(bigfix_t, x) * JAS_CAST(bigfix_t, y)) >> \
160 (fracbits))193 (fracbits))
161 194
162/* Calculate the product of two fixed-point numbers with overflow195/*! Calculate the product of two fixed-point numbers with overflow
163 checking. */196 checking. */
164#define JAS_FIX_MUL_OFLOW(fix_t, fracbits, bigfix_t, x, y) \197#define JAS_FIX_MUL_OFLOW(fix_t, fracbits, bigfix_t, x, y) \
165 ((JAS_CAST(bigfix_t, x) * JAS_CAST(bigfix_t, y) >> (fracbits)) == \198 ((JAS_CAST(bigfix_t, x) * JAS_CAST(bigfix_t, y) >> (fracbits)) == \
@@ -168,87 +201,87 @@ extern "C" { · 2 unmodified lines
168 JAS_CAST(fix_t, (JAS_CAST(bigfix_t, x) * JAS_CAST(bigfix_t, y) >> \201 JAS_CAST(fix_t, (JAS_CAST(bigfix_t, x) * JAS_CAST(bigfix_t, y) >> \
169 (fracbits))) : JAS_FIX_OFLOW())202 (fracbits))) : JAS_FIX_OFLOW())
170 203
171/* Calculate the product of a fixed-point number and an int. */204/*! Calculate the product of a fixed-point number and an int. */
172#if !defined(DEBUG_OVERFLOW)205#if !defined(DEBUG_OVERFLOW)
173#define JAS_FIX_MULBYINT JAS_FIX_MULBYINT_FAST206#define JAS_FIX_MULBYINT JAS_FIX_MULBYINT_FAST
174#else207#else
175#define JAS_FIX_MULBYINT JAS_FIX_MULBYINT_OFLOW208#define JAS_FIX_MULBYINT JAS_FIX_MULBYINT_OFLOW
176#endif209#endif
177 210
178/* Calculate the product of a fixed-point number and an int without overflow211/*! Calculate the product of a fixed-point number and an int without overflow
179 checking. */212 checking. */
180#define JAS_FIX_MULBYINT_FAST(fix_t, fracbits, x, y) \213#define JAS_FIX_MULBYINT_FAST(fix_t, fracbits, x, y) \
181 JAS_CAST(fix_t, ((x) * (y)))214 JAS_CAST(fix_t, ((x) * (y)))
182 215
183/* Calculate the product of a fixed-point number and an int with overflow216/*! Calculate the product of a fixed-point number and an int with overflow
184 checking. */217 checking. */
185#define JAS_FIX_MULBYINT_OFLOW(fix_t, fracbits, x, y) \218#define JAS_FIX_MULBYINT_OFLOW(fix_t, fracbits, x, y) \
186 JAS_FIX_MULBYINT_FAST(fix_t, fracbits, x, y)219 JAS_FIX_MULBYINT_FAST(fix_t, fracbits, x, y)
187 220
188/* Calculate the quotient of two fixed-point numbers. */221/*! Calculate the quotient of two fixed-point numbers. */
189#if !defined(DEBUG_OVERFLOW)222#if !defined(DEBUG_OVERFLOW)
190#define JAS_FIX_DIV JAS_FIX_DIV_FAST223#define JAS_FIX_DIV JAS_FIX_DIV_FAST
191#else224#else
192#define JAS_FIX_DIV JAS_FIX_DIV_UFLOW225#define JAS_FIX_DIV JAS_FIX_DIV_UFLOW
193#endif226#endif
194 227
195/* Calculate the quotient of two fixed-point numbers without underflow228/*! Calculate the quotient of two fixed-point numbers without underflow
196 checking. */229 checking. */
197#define JAS_FIX_DIV_FAST(fix_t, fracbits, bigfix_t, x, y) \230#define JAS_FIX_DIV_FAST(fix_t, fracbits, bigfix_t, x, y) \
198 JAS_CAST(fix_t, (JAS_CAST(bigfix_t, x) << (fracbits)) / (y))231 JAS_CAST(fix_t, (JAS_CAST(bigfix_t, x) << (fracbits)) / (y))
199 232
200/* Calculate the quotient of two fixed-point numbers with underflow233/*! Calculate the quotient of two fixed-point numbers with underflow
201 checking. */234 checking. */
202#define JAS_FIX_DIV_UFLOW(fix_t, fracbits, bigfix_t, x, y) \235#define JAS_FIX_DIV_UFLOW(fix_t, fracbits, bigfix_t, x, y) \
203 JAS_FIX_DIV_FAST(fix_t, fracbits, bigfix_t, x, y)236 JAS_FIX_DIV_FAST(fix_t, fracbits, bigfix_t, x, y)
204 237
205/* Negate a fixed-point number. */238/*! Negate a fixed-point number. */
206#if !defined(DEBUG_OVERFLOW)239#if !defined(DEBUG_OVERFLOW)
207#define JAS_FIX_NEG JAS_FIX_NEG_FAST240#define JAS_FIX_NEG JAS_FIX_NEG_FAST
208#else241#else
209#define JAS_FIX_NEG JAS_FIX_NEG_OFLOW242#define JAS_FIX_NEG JAS_FIX_NEG_OFLOW
210#endif243#endif
211 244
212/* Negate a fixed-point number without overflow checking. */245/*! Negate a fixed-point number without overflow checking. */
213#define JAS_FIX_NEG_FAST(fix_t, fracbits, x) \246#define JAS_FIX_NEG_FAST(fix_t, fracbits, x) \
214 (-(x))247 (-(x))
215 248
216/* Negate a fixed-point number with overflow checking. */249/*! Negate a fixed-point number with overflow checking. */
217/* Yes, overflow is actually possible for two's complement representations,250/* Yes, overflow is actually possible for two's complement representations,
218 although highly unlikely to occur. */251 although highly unlikely to occur. */
219#define JAS_FIX_NEG_OFLOW(fix_t, fracbits, x) \252#define JAS_FIX_NEG_OFLOW(fix_t, fracbits, x) \
220 (((x) < 0) ? (-(x) > 0 || JAS_FIX_OFLOW(), -(x)) : (-(x)))253 (((x) < 0) ? (-(x) > 0 || JAS_FIX_OFLOW(), -(x)) : (-(x)))
221 254
222/* Perform an arithmetic shift left of a fixed-point number. */255/*! Perform an arithmetic shift left of a fixed-point number. */
223#if !defined(DEBUG_OVERFLOW)256#if !defined(DEBUG_OVERFLOW)
224#define JAS_FIX_ASL JAS_FIX_ASL_FAST257#define JAS_FIX_ASL JAS_FIX_ASL_FAST
225#else258#else
226#define JAS_FIX_ASL JAS_FIX_ASL_OFLOW259#define JAS_FIX_ASL JAS_FIX_ASL_OFLOW
227#endif260#endif
228 261
229/* Perform an arithmetic shift left of a fixed-point number without overflow262/*! Perform an arithmetic shift left of a fixed-point number without overflow
230 checking. */263 checking. */
231#define JAS_FIX_ASL_FAST(fix_t, fracbits, x, n) \264#define JAS_FIX_ASL_FAST(fix_t, fracbits, x, n) \
232 ((x) << (n))265 ((x) << (n))
233 266
234/* Perform an arithmetic shift left of a fixed-point number with overflow267/*! Perform an arithmetic shift left of a fixed-point number with overflow
235 checking. */268 checking. */
236#define JAS_FIX_ASL_OFLOW(fix_t, fracbits, x, n) \269#define JAS_FIX_ASL_OFLOW(fix_t, fracbits, x, n) \
237 ((((x) << (n)) >> (n)) == (x) || JAS_FIX_OFLOW(), (x) << (n))270 ((((x) << (n)) >> (n)) == (x) || JAS_FIX_OFLOW(), (x) << (n))
238 271
239/* Perform an arithmetic shift right of a fixed-point number. */272/*! Perform an arithmetic shift right of a fixed-point number. */
240#if !defined(DEBUG_OVERFLOW)273#if !defined(DEBUG_OVERFLOW)
241#define JAS_FIX_ASR JAS_FIX_ASR_FAST274#define JAS_FIX_ASR JAS_FIX_ASR_FAST
242#else275#else
243#define JAS_FIX_ASR JAS_FIX_ASR_UFLOW276#define JAS_FIX_ASR JAS_FIX_ASR_UFLOW
244#endif277#endif
245 278
246/* Perform an arithmetic shift right of a fixed-point number without underflow279/*! Perform an arithmetic shift right of a fixed-point number without underflow
247 checking. */280 checking. */
248#define JAS_FIX_ASR_FAST(fix_t, fracbits, x, n) \281#define JAS_FIX_ASR_FAST(fix_t, fracbits, x, n) \
249 ((x) >> (n))282 ((x) >> (n))
250 283
251/* Perform an arithmetic shift right of a fixed-point number with underflow284/*! Perform an arithmetic shift right of a fixed-point number with underflow
252 checking. */285 checking. */
253#define JAS_FIX_ASR_UFLOW(fix_t, fracbits, x, n) \286#define JAS_FIX_ASR_UFLOW(fix_t, fracbits, x, n) \
254 JAS_FIX_ASR_FAST(fix_t, fracbits, x, n)287 JAS_FIX_ASR_FAST(fix_t, fracbits, x, n)
@@ -257,19 +290,19 @@ extern "C" { · 2 unmodified lines
257* Other basic arithmetic operations.290* Other basic arithmetic operations.
258\******************************************************************************/291\******************************************************************************/
259 292
260/* Calculate the difference between two fixed-point numbers. */293/*! Calculate the difference between two fixed-point numbers. */
261#define JAS_FIX_SUB(fix_t, fracbits, x, y) \294#define JAS_FIX_SUB(fix_t, fracbits, x, y) \
262 JAS_FIX_ADD(fix_t, fracbits, x, JAS_FIX_NEG(fix_t, fracbits, y))295 JAS_FIX_ADD(fix_t, fracbits, x, JAS_FIX_NEG(fix_t, fracbits, y))
263 296
264/* Add one fixed-point number to another. */297/*! Add one fixed-point number to another. */
265#define JAS_FIX_PLUSEQ(fix_t, fracbits, x, y) \298#define JAS_FIX_PLUSEQ(fix_t, fracbits, x, y) \
266 ((x) = JAS_FIX_ADD(fix_t, fracbits, x, y))299 ((x) = JAS_FIX_ADD(fix_t, fracbits, x, y))
267 300
268/* Subtract one fixed-point number from another. */301/*! Subtract one fixed-point number from another. */
269#define JAS_FIX_MINUSEQ(fix_t, fracbits, x, y) \302#define JAS_FIX_MINUSEQ(fix_t, fracbits, x, y) \
270 ((x) = JAS_FIX_SUB(fix_t, fracbits, x, y))303 ((x) = JAS_FIX_SUB(fix_t, fracbits, x, y))
271 304
272/* Multiply one fixed-point number by another. */305/*! Multiply one fixed-point number by another. */
273#define JAS_FIX_MULEQ(fix_t, fracbits, bigfix_t, x, y) \306#define JAS_FIX_MULEQ(fix_t, fracbits, bigfix_t, x, y) \
274 ((x) = JAS_FIX_MUL(fix_t, fracbits, bigfix_t, x, y))307 ((x) = JAS_FIX_MUL(fix_t, fracbits, bigfix_t, x, y))
275 308
@@ -277,15 +310,15 @@ extern "C" { · 1 unmodified line
277* Miscellaneous operations.310* Miscellaneous operations.
278\******************************************************************************/311\******************************************************************************/
279 312
280/* Calculate the absolute value of a fixed-point number. */313/*! Calculate the absolute value of a fixed-point number. */
281#define JAS_FIX_ABS(fix_t, fracbits, x) \314#define JAS_FIX_ABS(fix_t, fracbits, x) \
282 (((x) >= 0) ? (x) : (JAS_FIX_NEG(fix_t, fracbits, x)))315 (((x) >= 0) ? (x) : (JAS_FIX_NEG(fix_t, fracbits, x)))
283 316
284/* Is a fixed-point number an integer? */317/*! Is a fixed-point number an integer? */
285#define JAS_FIX_ISINT(fix_t, fracbits, x) \318#define JAS_FIX_ISINT(fix_t, fracbits, x) \
286 (JAS_FIX_FLOOR(fix_t, fracbits, x) == (x))319 (JAS_FIX_FLOOR(fix_t, fracbits, x) == (x))
287 320
288/* Get the sign of a fixed-point number. */321/*! Get the sign of a fixed-point number. */
289#define JAS_FIX_SGN(fix_t, fracbits, x) \322#define JAS_FIX_SGN(fix_t, fracbits, x) \
290 ((x) >= 0 ? 1 : (-1))323 ((x) >= 0 ? 1 : (-1))
291 324
@@ -293,23 +326,23 @@ extern "C" { · 1 unmodified line
293* Relational operations.326* Relational operations.
294\******************************************************************************/327\******************************************************************************/
295 328
296/* Compare two fixed-point numbers. */329/*! Compare two fixed-point numbers. */
297#define JAS_FIX_CMP(fix_t, fracbits, x, y) \330#define JAS_FIX_CMP(fix_t, fracbits, x, y) \
298 ((x) > (y) ? 1 : (((x) == (y)) ? 0 : (-1)))331 ((x) > (y) ? 1 : (((x) == (y)) ? 0 : (-1)))
299 332
300/* Less than. */333/*! Less than. */
301#define JAS_FIX_LT(fix_t, fracbits, x, y) \334#define JAS_FIX_LT(fix_t, fracbits, x, y) \
302 ((x) < (y))335 ((x) < (y))
303 336
304/* Less than or equal. */337/*! Less than or equal. */
305#define JAS_FIX_LTE(fix_t, fracbits, x, y) \338#define JAS_FIX_LTE(fix_t, fracbits, x, y) \
306 ((x) <= (y))339 ((x) <= (y))
307 340
308/* Greater than. */341/*! Greater than. */
309#define JAS_FIX_GT(fix_t, fracbits, x, y) \342#define JAS_FIX_GT(fix_t, fracbits, x, y) \
310 ((x) > (y))343 ((x) > (y))
311 344
312/* Greater than or equal. */345/*! Greater than or equal. */
313#define JAS_FIX_GTE(fix_t, fracbits, x, y) \346#define JAS_FIX_GTE(fix_t, fracbits, x, y) \
314 ((x) >= (y))347 ((x) >= (y))
315 348
@@ -317,14 +350,14 @@ extern "C" { · 1 unmodified line
317* Rounding functions.350* Rounding functions.
318\******************************************************************************/351\******************************************************************************/
319 352
320/* Round a fixed-point number to the nearest integer. */353/*! Round a fixed-point number to the nearest integer. */
321#define JAS_FIX_ROUND(fix_t, fracbits, x) \354#define JAS_FIX_ROUND(fix_t, fracbits, x) \
322 (((x) < 0) ? JAS_FIX_FLOOR(fix_t, fracbits, JAS_FIX_ADD(fix_t, fracbits, \355 (((x) < 0) ? JAS_FIX_FLOOR(fix_t, fracbits, JAS_FIX_ADD(fix_t, fracbits, \
323 (x), JAS_FIX_HALF(fix_t, fracbits))) : \356 (x), JAS_FIX_HALF(fix_t, fracbits))) : \
324 JAS_FIX_NEG(fix_t, fracbits, JAS_FIX_FLOOR(fix_t, fracbits, \357 JAS_FIX_NEG(fix_t, fracbits, JAS_FIX_FLOOR(fix_t, fracbits, \
325 JAS_FIX_ADD(fix_t, fracbits, (-(x)), JAS_FIX_HALF(fix_t, fracbits)))))358 JAS_FIX_ADD(fix_t, fracbits, (-(x)), JAS_FIX_HALF(fix_t, fracbits)))))
326 359
327/* Round a fixed-point number to the nearest integer in the direction of360/*! Round a fixed-point number to the nearest integer in the direction of
328 negative infinity (i.e., the floor function). */361 negative infinity (i.e., the floor function). */
329#define JAS_FIX_FLOOR(fix_t, fracbits, x) \362#define JAS_FIX_FLOOR(fix_t, fracbits, x) \
330 ((x) & (~(JAS_FIX_ONE(fix_t, fracbits) - 1)))363 ((x) & (~(JAS_FIX_ONE(fix_t, fracbits) - 1)))
@@ -336,11 +369,31 @@ extern "C" { · 5 unmodified lines
336 369
337/* Handle overflow. */370/* Handle overflow. */
338#define JAS_FIX_OFLOW() \371#define JAS_FIX_OFLOW() \
339 jas_eprintf("overflow error: file %s, line %d\n", __FILE__, __LINE__)372 jas_logerrorf("overflow error: file %s, line %d\n", __FILE__, __LINE__)
340 373
341/* Handle underflow. */374/* Handle underflow. */
342#define JAS_FIX_UFLOW() \375#define JAS_FIX_UFLOW() \
343 jas_eprintf("underflow error: file %s, line %d\n", __FILE__, __LINE__)376 jas_logerrorf("underflow error: file %s, line %d\n", __FILE__, __LINE__)
377
378/******************************************************************************\
379*
380\******************************************************************************/
381
382JAS_ATTRIBUTE_DISABLE_UBSAN
383static inline jas_fix_t jas_fix_asl(jas_fix_t x, unsigned n)
384{
385 return JAS_FIX_ASL(jas_fix_t, 0, x, n);
386}
387
388JAS_ATTRIBUTE_DISABLE_UBSAN
389static inline jas_fix_t jas_fix_asr(jas_fix_t x, unsigned n)
390{
391 return JAS_FIX_ASR(jas_fix_t, 0, x, n);
392}
393
394/*!
395 * @}
396 */
344 397
345#ifdef __cplusplus398#ifdef __cplusplus
346}399}
jasper/jas_icc.h+142−20
@@ -77,6 +77,11 @@ · 76 unmodified lines
77extern "C" {77extern "C" {
78#endif78#endif
79 79
80/*!
81 * @addtogroup module_cm
82 * @{
83 */
84
80/* Profile file signature. */85/* Profile file signature. */
81#define JAS_ICC_MAGIC 0x6163737086#define JAS_ICC_MAGIC 0x61637370
82 87
@@ -308,6 +313,7 @@ typedef struct { · 225 unmodified lines
308 int (*output)(struct jas_iccattrval_s *, jas_stream_t *);313 int (*output)(struct jas_iccattrval_s *, jas_stream_t *);
309//#endif314//#endif
310 unsigned (*getsize)(const struct jas_iccattrval_s *);315 unsigned (*getsize)(const struct jas_iccattrval_s *);
316 void (*dump)(const struct jas_iccattrval_s *, FILE *);
311} jas_iccattrvalops_t;317} jas_iccattrvalops_t;
312 318
313/* Attribute value type (type and value information). */319/* Attribute value type (type and value information). */
@@ -381,29 +387,145 @@ typedef struct { · 67 unmodified lines
381 jas_iccattrvalops_t ops;387 jas_iccattrvalops_t ops;
382} jas_iccattrvalinfo_t;388} jas_iccattrvalinfo_t;
383 389
384JAS_DLLEXPORT jas_iccprof_t *jas_iccprof_load(jas_stream_t *in);390/*!
385JAS_DLLEXPORT int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out);391@brief
386JAS_DLLEXPORT void jas_iccprof_destroy(jas_iccprof_t *prof);392Read an ICC profile from a stream.
393*/
394JAS_EXPORT
395jas_iccprof_t *jas_iccprof_load(jas_stream_t *in);
396
397/*!
398@brief
399Write an ICC profile to a stream.
400*/
401JAS_EXPORT
402int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out);
403
404/*!
405@brief
406Destroy an ICC profile.
407*/
408JAS_EXPORT
409void jas_iccprof_destroy(jas_iccprof_t *prof);
410
411/*!
412@brief
413Get an attribute of an ICC profile.
414*/
387JAS_ATTRIBUTE_PURE415JAS_ATTRIBUTE_PURE
388JAS_DLLEXPORT jas_iccattrval_t *jas_iccprof_getattr(const jas_iccprof_t *prof,416JAS_EXPORT
417jas_iccattrval_t *jas_iccprof_getattr(const jas_iccprof_t *prof,
389 jas_iccattrname_t name);418 jas_iccattrname_t name);
390JAS_DLLEXPORT int jas_iccprof_setattr(jas_iccprof_t *prof, jas_iccattrname_t name,419
420/*!
421@brief
422Set an attribute of an ICC profile.
423*/
424JAS_EXPORT
425int jas_iccprof_setattr(jas_iccprof_t *prof, jas_iccattrname_t name,
391 jas_iccattrval_t *val);426 jas_iccattrval_t *val);
392JAS_DLLEXPORT int jas_iccprof_gethdr(const jas_iccprof_t *prof, jas_icchdr_t *hdr);427
393JAS_DLLEXPORT int jas_iccprof_sethdr(jas_iccprof_t *prof, const jas_icchdr_t *hdr);428/*!
394 429@brief
395JAS_DLLEXPORT void jas_iccattrval_destroy(jas_iccattrval_t *attrval);430Dump an ICC profile to a stream in human-readable format
396JAS_DLLEXPORT int jas_iccattrval_allowmodify(jas_iccattrval_t **attrval);431for debugging purposes.
397JAS_DLLEXPORT jas_iccattrval_t *jas_iccattrval_clone(jas_iccattrval_t *attrval);432*/
398JAS_DLLEXPORT jas_iccattrval_t *jas_iccattrval_create(jas_iccuint32_t type);433JAS_EXPORT
399 434void jas_iccprof_dump(const jas_iccprof_t *prof, FILE *out);
400JAS_DLLEXPORT extern const jas_uchar jas_iccprofdata_srgb[];435
401JAS_DLLEXPORT extern const unsigned jas_iccprofdata_srgblen;436/*!
402JAS_DLLEXPORT extern const jas_uchar jas_iccprofdata_sgray[];437@brief
403JAS_DLLEXPORT extern const unsigned jas_iccprofdata_sgraylen;438Create a copy of an ICC profile.
404JAS_DLLEXPORT jas_iccprof_t *jas_iccprof_createfrombuf(const jas_uchar *buf, unsigned len);439*/
405JAS_DLLEXPORT jas_iccprof_t *jas_iccprof_createfromclrspc(unsigned clrspc);440JAS_EXPORT
406JAS_DLLEXPORT jas_iccprof_t *jas_iccprof_copy(const jas_iccprof_t *prof);441jas_iccprof_t *jas_iccprof_copy(const jas_iccprof_t *prof);
442
443/*!
444@brief
445Get the header for an ICC profile.
446*/
447JAS_EXPORT
448int jas_iccprof_gethdr(const jas_iccprof_t *prof, jas_icchdr_t *hdr);
449
450/*!
451@brief
452Set the header for an ICC profile.
453*/
454JAS_EXPORT
455int jas_iccprof_sethdr(jas_iccprof_t *prof, const jas_icchdr_t *hdr);
456
457/*!
458@brief
459Destroy an ICC profile attribute.
460*/
461JAS_EXPORT
462void jas_iccattrval_destroy(jas_iccattrval_t *attrval);
463
464/*!
465@brief
466*/
467JAS_EXPORT
468void jas_iccattrval_dump(const jas_iccattrval_t *attrval, FILE *out);
469
470/*!
471@brief
472
473TODO/FIXME
474*/
475JAS_EXPORT
476int jas_iccattrval_allowmodify(jas_iccattrval_t **attrval);
477
478/*!
479@brief
480Create a copy of an ICC profile attribute.
481*/
482JAS_EXPORT
483jas_iccattrval_t *jas_iccattrval_clone(jas_iccattrval_t *attrval);
484
485/*!
486@brief
487Create an ICC profile attribute.
488*/
489JAS_EXPORT
490jas_iccattrval_t *jas_iccattrval_create(jas_iccuint32_t type);
491
492/*!
493@brief
494Dump an ICC profile attribute to a stream in human-readable format
495for debugging purposes.
496*/
497JAS_EXPORT
498void jas_iccattrtab_dump(const jas_iccattrtab_t *attrtab, FILE *out);
499
500/*!
501@brief
502Create an ICC profile from a buffer in memory.
503*/
504JAS_EXPORT
505jas_iccprof_t *jas_iccprof_createfrombuf(const jas_uchar *buf, unsigned len);
506
507/*!
508@brief
509Create an ICC profile from a color space.
510*/
511JAS_EXPORT
512jas_iccprof_t *jas_iccprof_createfromclrspc(unsigned clrspc);
513
514JAS_EXPORT
515extern const jas_uchar jas_iccprofdata_srgb[];
516
517JAS_EXPORT
518extern const unsigned jas_iccprofdata_srgblen;
519
520JAS_EXPORT
521extern const jas_uchar jas_iccprofdata_sgray[];
522
523JAS_EXPORT
524extern const unsigned jas_iccprofdata_sgraylen;
525
526/*!
527 * @}
528 */
407 529
408#ifdef __cplusplus530#ifdef __cplusplus
409}531}
jasper/jas_image.h+222−100
@@ -86,7 +86,7 @@ extern "C" { · 85 unmodified lines
86#endif86#endif
87 87
88/*!88/*!
89 * @addtogroup image89 * @addtogroup module_images
90 * @{90 * @{
91 */91 */
92 92
@@ -128,7 +128,8 @@ extern "C" { · 35 unmodified lines
128\******************************************************************************/128\******************************************************************************/
129 129
130/*!130/*!
131@brief Image coordinate. */131@brief Image coordinate.
132*/
132typedef int_fast32_t jas_image_coord_t;133typedef int_fast32_t jas_image_coord_t;
133#define JAS_IMAGE_COORD_MAX INT_FAST32_MAX134#define JAS_IMAGE_COORD_MAX INT_FAST32_MAX
134#define JAS_IMAGE_COORD_MIN INT_FAST32_MIN135#define JAS_IMAGE_COORD_MIN INT_FAST32_MIN
@@ -154,81 +155,95 @@ typedef int_fast16_t jas_image_smpltype_t; · 19 unmodified lines
154\******************************************************************************/155\******************************************************************************/
155 156
156/*!157/*!
157@brief Image component class.158@brief
159Image component class.
160
161@warning
162Library users should never directly access any of the members of this
163class.
164The functions/macros provided by the JasPer library API should always
165be used.
158*/166*/
159typedef struct {167typedef struct {
160 168
161 jas_image_coord_t tlx_;
162 /* The x-coordinate of the top-left corner of the component. */169 /* The x-coordinate of the top-left corner of the component. */
170 jas_image_coord_t tlx_;
163 171
164 jas_image_coord_t tly_;
165 /* The y-coordinate of the top-left corner of the component. */172 /* The y-coordinate of the top-left corner of the component. */
173 jas_image_coord_t tly_;
166 174
167 jas_image_coord_t hstep_;
168 /* The horizontal sampling period in units of the reference grid. */175 /* The horizontal sampling period in units of the reference grid. */
176 jas_image_coord_t hstep_;
169 177
170 jas_image_coord_t vstep_;
171 /* The vertical sampling period in units of the reference grid. */178 /* The vertical sampling period in units of the reference grid. */
179 jas_image_coord_t vstep_;
172 180
173 jas_image_coord_t width_;
174 /* The component width in samples. */181 /* The component width in samples. */
182 jas_image_coord_t width_;
175 183
176 jas_image_coord_t height_;
177 /* The component height in samples. */184 /* The component height in samples. */
185 jas_image_coord_t height_;
178 186
187 /* The precision of the sample data (i.e., the number of bits per sample).
188 If the samples are signed values, this quantity includes the sign bit. */
179 unsigned prec_;189 unsigned prec_;
180 /* The precision of the sample data (i.e., the number of bits per
181 sample). If the samples are signed values, this quantity
182 includes the sign bit. */
183 190
184 int sgnd_;
185 /* The signedness of the sample data. */191 /* The signedness of the sample data. */
192 int sgnd_;
186 193
187 jas_stream_t *stream_;
188 /* The stream containing the component data. */194 /* The stream containing the component data. */
195 jas_stream_t *stream_;
189 196
190 unsigned cps_;
191 /* The number of characters per sample in the stream. */197 /* The number of characters per sample in the stream. */
198 unsigned cps_;
192 199
193 jas_image_cmpttype_t type_;
194 /* The type of component (e.g., opacity, red, green, blue, luma). */200 /* The type of component (e.g., opacity, red, green, blue, luma). */
201 jas_image_cmpttype_t type_;
195 202
196} jas_image_cmpt_t;203} jas_image_cmpt_t;
197 204
198/*!205/*!
199@brief Image class.206@brief Image class.
207
208@warning
209Library users should never directly access any of the members of this
210class.
211The functions/macros provided by the JasPer library API should always
212be used.
200*/213*/
201typedef struct {214typedef struct {
202 215
203 jas_image_coord_t tlx_;
204 /* The x-coordinate of the top-left corner of the image bounding box. */216 /* The x-coordinate of the top-left corner of the image bounding box. */
217 jas_image_coord_t tlx_;
205 218
206 jas_image_coord_t tly_;
207 /* The y-coordinate of the top-left corner of the image bounding box. */219 /* The y-coordinate of the top-left corner of the image bounding box. */
220 jas_image_coord_t tly_;
208 221
209 jas_image_coord_t brx_;
210 /* The x-coordinate of the bottom-right corner of the image bounding222 /* The x-coordinate of the bottom-right corner of the image bounding
211 box (plus one). */223 box (plus one). */
224 jas_image_coord_t brx_;
212 225
213 jas_image_coord_t bry_;
214 /* The y-coordinate of the bottom-right corner of the image bounding226 /* The y-coordinate of the bottom-right corner of the image bounding
215 box (plus one). */227 box (plus one). */
228 jas_image_coord_t bry_;
216 229
217 unsigned numcmpts_;
218 /* The number of components. */230 /* The number of components. */
231 unsigned numcmpts_;
219 232
220 unsigned maxcmpts_;
221 /* The maximum number of components that this image can have (i.e., the233 /* The maximum number of components that this image can have (i.e., the
222 allocated size of the components array). */234 allocated size of the components array). */
235 unsigned maxcmpts_;
223 236
224 jas_image_cmpt_t **cmpts_;
225 /* Per-component information. */237 /* Per-component information. */
238 jas_image_cmpt_t **cmpts_;
226 239
240 /* The color space. */
227 jas_clrspc_t clrspc_;241 jas_clrspc_t clrspc_;
228 242
243 /* The CM profile. */
229 jas_cmprof_t *cmprof_;244 jas_cmprof_t *cmprof_;
230 245
231// bool inmem_;246 //bool inmem_;
232 247
233} jas_image_t;248} jas_image_t;
234 249
@@ -241,29 +256,29 @@ jas_image_create function. · 6 unmodified lines
241*/256*/
242typedef struct {257typedef struct {
243 258
244 jas_image_coord_t tlx;
245 /* The x-coordinate of the top-left corner of the component. */259 /* The x-coordinate of the top-left corner of the component. */
260 jas_image_coord_t tlx;
246 261
247 jas_image_coord_t tly;
248 /* The y-coordinate of the top-left corner of the component. */262 /* The y-coordinate of the top-left corner of the component. */
263 jas_image_coord_t tly;
249 264
250 jas_image_coord_t hstep;
251 /* The horizontal sampling period in units of the reference grid. */265 /* The horizontal sampling period in units of the reference grid. */
266 jas_image_coord_t hstep;
252 267
253 jas_image_coord_t vstep;
254 /* The vertical sampling period in units of the reference grid. */268 /* The vertical sampling period in units of the reference grid. */
269 jas_image_coord_t vstep;
255 270
256 jas_image_coord_t width;
257 /* The width of the component in samples. */271 /* The width of the component in samples. */
272 jas_image_coord_t width;
258 273
259 jas_image_coord_t height;
260 /* The height of the component in samples. */274 /* The height of the component in samples. */
275 jas_image_coord_t height;
261 276
262 unsigned prec;
263 /* The precision of the component sample data. */277 /* The precision of the component sample data. */
278 unsigned prec;
264 279
265 int sgnd;
266 /* The signedness of the component sample data. */280 /* The signedness of the component sample data. */
281 int sgnd;
267 282
268} jas_image_cmptparm_t;283} jas_image_cmptparm_t;
269 284
@@ -281,14 +296,14 @@ typedef struct { · 11 unmodified lines
281*/296*/
282typedef struct {297typedef struct {
283 298
299 /*! Decode image data from a stream. */
284 jas_image_t *(*decode)(jas_stream_t *in, const char *opts);300 jas_image_t *(*decode)(jas_stream_t *in, const char *opts);
285 /* Decode image data from a stream. */
286 301
302 /*! Encode image data to a stream. */
287 int (*encode)(jas_image_t *image, jas_stream_t *out, const char *opts);303 int (*encode)(jas_image_t *image, jas_stream_t *out, const char *opts);
288 /* Encode image data to a stream. */
289 304
305 /*! Determine if stream data is in a particular format. */
290 int (*validate)(jas_stream_t *in);306 int (*validate)(jas_stream_t *in);
291 /* Determine if stream data is in a particular format. */
292 307
293} jas_image_fmtops_t;308} jas_image_fmtops_t;
294 309
@@ -297,20 +312,29 @@ typedef struct { · 2 unmodified lines
297*/312*/
298typedef struct {313typedef struct {
299 314
315 /*! The ID for this format. */
300 int id;316 int id;
301 /* The ID for this format. */
302 317
318 /*! The name by which this format is identified. */
303 char *name;319 char *name;
304 /* The name by which this format is identified. */
305 320
321 /* The primary file name extension associated with this format. */
322 /* This member only exists for backward compatibility. */
306 char *ext;323 char *ext;
307 /* The file name extension associated with this format. */
308 324
325 /*! The table of file name extensions associated with this format. */
326 char **exts;
327 size_t max_exts;
328 size_t num_exts;
329
330 /*! A boolean flag indicating if this format is enabled. */
331 int enabled;
332
333 /*! A brief description of the format. */
309 char *desc;334 char *desc;
310 /* A brief description of the format. */
311 335
336 /*! The operations for this format. */
312 jas_image_fmtops_t ops;337 jas_image_fmtops_t ops;
313 /* The operations for this format. */
314 338
315} jas_image_fmtinfo_t;339} jas_image_fmtinfo_t;
316 340
@@ -321,23 +345,27 @@ typedef struct { · 4 unmodified lines
321/*!345/*!
322@brief Create an image.346@brief Create an image.
323*/347*/
324JAS_DLLEXPORT jas_image_t *jas_image_create(unsigned numcmpts,348JAS_EXPORT
349jas_image_t *jas_image_create(unsigned numcmpts,
325 const jas_image_cmptparm_t *cmptparms, jas_clrspc_t clrspc);350 const jas_image_cmptparm_t *cmptparms, jas_clrspc_t clrspc);
326 351
327/*!352/*!
328@brief Create an "empty" image.353@brief Create an "empty" image.
329*/354*/
330JAS_DLLEXPORT jas_image_t *jas_image_create0(void);355JAS_EXPORT
356jas_image_t *jas_image_create0(void);
331 357
332/*!358/*!
333@brief Clone an image.359@brief Clone an image.
334*/360*/
335JAS_DLLEXPORT jas_image_t *jas_image_copy(jas_image_t *image);361JAS_EXPORT
362jas_image_t *jas_image_copy(jas_image_t *image);
336 363
337/*!364/*!
338@brief Deallocate any resources associated with an image.365@brief Deallocate any resources associated with an image.
339*/366*/
340JAS_DLLEXPORT void jas_image_destroy(jas_image_t *image);367JAS_EXPORT
368void jas_image_destroy(jas_image_t *image);
341 369
342/*!370/*!
343@brief Get the width of the image in units of the image reference grid.371@brief Get the width of the image in units of the image reference grid.
@@ -470,26 +498,27 @@ box on the reference grid (plus one). · 126 unmodified lines
470@brief Test if all components are specified at the same positions in space.498@brief Test if all components are specified at the same positions in space.
471*/499*/
472JAS_ATTRIBUTE_PURE500JAS_ATTRIBUTE_PURE
473JAS_DLLEXPORT bool jas_image_cmpt_domains_same(const jas_image_t *image);501JAS_EXPORT
502bool jas_image_cmpt_domains_same(const jas_image_t *image);
474 503
475/*!504/*!
476@brief Get the raw size of an image505@brief Get the raw size of an image
477(i.e., the nominal size of the image without any compression.506(i.e., the nominal size of the image without any compression.
478*/507*/
479JAS_ATTRIBUTE_PURE508JAS_ATTRIBUTE_PURE
480JAS_DLLEXPORT509JAS_EXPORT
481uint_fast32_t jas_image_rawsize(const jas_image_t *image);510uint_fast32_t jas_image_rawsize(const jas_image_t *image);
482 511
483/*!512/*!
484@brief Create an image from a stream in some specified format.513@brief Create an image from a stream in some specified format.
485*/514*/
486JAS_DLLEXPORT515JAS_EXPORT
487jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, const char *optstr);516jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, const char *optstr);
488 517
489/*!518/*!
490@brief Write an image to a stream in a specified format.519@brief Write an image to a stream in a specified format.
491*/520*/
492JAS_DLLEXPORT521JAS_EXPORT
493int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt,522int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt,
494 const char *optstr);523 const char *optstr);
495 524
@@ -500,7 +529,7 @@ int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt, · 4 unmodified lines
500The position and size of the rectangular region to be read is specified529The position and size of the rectangular region to be read is specified
501relative to the component's coordinate system.530relative to the component's coordinate system.
502*/531*/
503JAS_DLLEXPORT532JAS_EXPORT
504int jas_image_readcmpt(jas_image_t *image, unsigned cmptno,533int jas_image_readcmpt(jas_image_t *image, unsigned cmptno,
505 jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,534 jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,
506 jas_image_coord_t height, jas_matrix_t *data);535 jas_image_coord_t height, jas_matrix_t *data);
@@ -508,7 +537,7 @@ int jas_image_readcmpt(jas_image_t *image, unsigned cmptno, · 1 unmodified line
508/*!537/*!
509@brief Write a rectangular region of an image component.538@brief Write a rectangular region of an image component.
510*/539*/
511JAS_DLLEXPORT540JAS_EXPORT
512int jas_image_writecmpt(jas_image_t *image, unsigned cmptno,541int jas_image_writecmpt(jas_image_t *image, unsigned cmptno,
513 jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,542 jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,
514 jas_image_coord_t height, const jas_matrix_t *data);543 jas_image_coord_t height, const jas_matrix_t *data);
@@ -516,18 +545,21 @@ int jas_image_writecmpt(jas_image_t *image, unsigned cmptno, · 1 unmodified line
516/*!545/*!
517@brief Delete a component from an image.546@brief Delete a component from an image.
518*/547*/
519JAS_DLLEXPORT void jas_image_delcmpt(jas_image_t *image, unsigned cmptno);548JAS_EXPORT
549void jas_image_delcmpt(jas_image_t *image, unsigned cmptno);
520 550
521/*!551/*!
522@brief Add a component to an image.552@brief Add a component to an image.
523*/553*/
524JAS_DLLEXPORT int jas_image_addcmpt(jas_image_t *image, int cmptno,554JAS_EXPORT
555int jas_image_addcmpt(jas_image_t *image, int cmptno,
525 const jas_image_cmptparm_t *cmptparm);556 const jas_image_cmptparm_t *cmptparm);
526 557
527/*!558/*!
528@brief Copy a component from one image to another.559@brief Copy a component from one image to another.
529*/560*/
530JAS_DLLEXPORT int jas_image_copycmpt(jas_image_t *dstimage, unsigned dstcmptno,561JAS_EXPORT
562int jas_image_copycmpt(jas_image_t *dstimage, unsigned dstcmptno,
531 jas_image_t *srcimage, unsigned srccmptno);563 jas_image_t *srcimage, unsigned srccmptno);
532 564
533JAS_ATTRIBUTE_CONST565JAS_ATTRIBUTE_CONST
@@ -555,7 +587,8 @@ static inline uint_least8_t JAS_IMAGE_CDT_SETPREC(uint_least8_t dtype) · 21 unmodified lines
555}587}
556 588
557JAS_ATTRIBUTE_PURE589JAS_ATTRIBUTE_PURE
558static inline uint_least8_t jas_image_cmptdtype(const jas_image_t *image, unsigned cmptno)590static inline uint_least8_t jas_image_cmptdtype(const jas_image_t *image,
591 unsigned cmptno)
559{592{
560 return JAS_IMAGE_CDT_SETSGND(image->cmpts_[cmptno]->sgnd_) |593 return JAS_IMAGE_CDT_SETSGND(image->cmpts_[cmptno]->sgnd_) |
561 JAS_IMAGE_CDT_SETPREC(image->cmpts_[cmptno]->prec_);594 JAS_IMAGE_CDT_SETPREC(image->cmpts_[cmptno]->prec_);
@@ -564,7 +597,7 @@ static inline uint_least8_t jas_image_cmptdtype(const jas_image_t *image, unsign · 2 unmodified lines
564/*!597/*!
565@brief Depalettize an image598@brief Depalettize an image
566*/599*/
567JAS_DLLEXPORT600JAS_EXPORT
568int jas_image_depalettize(jas_image_t *image, unsigned cmptno,601int jas_image_depalettize(jas_image_t *image, unsigned cmptno,
569 unsigned numlutents, const int_fast32_t *lutents, unsigned dtype,602 unsigned numlutents, const int_fast32_t *lutents, unsigned dtype,
570 unsigned newcmptno);603 unsigned newcmptno);
@@ -572,14 +605,14 @@ int jas_image_depalettize(jas_image_t *image, unsigned cmptno, · 1 unmodified line
572/*!605/*!
573@brief Read a component sample for an image.606@brief Read a component sample for an image.
574*/607*/
575JAS_DLLEXPORT608JAS_EXPORT
576int jas_image_readcmptsample(jas_image_t *image, unsigned cmptno, unsigned x,609int jas_image_readcmptsample(jas_image_t *image, unsigned cmptno, unsigned x,
577 unsigned y);610 unsigned y);
578 611
579/*!612/*!
580@brief Write a component sample for an image.613@brief Write a component sample for an image.
581*/614*/
582JAS_DLLEXPORT615JAS_EXPORT
583void jas_image_writecmptsample(jas_image_t *image, unsigned cmptno,616void jas_image_writecmptsample(jas_image_t *image, unsigned cmptno,
584 unsigned x, unsigned y, int_fast32_t v);617 unsigned x, unsigned y, int_fast32_t v);
585 618
@@ -587,7 +620,7 @@ void jas_image_writecmptsample(jas_image_t *image, unsigned cmptno, · 1 unmodified line
587@brief Get an image component by its type.620@brief Get an image component by its type.
588*/621*/
589JAS_ATTRIBUTE_PURE622JAS_ATTRIBUTE_PURE
590JAS_DLLEXPORT623JAS_EXPORT
591int jas_image_getcmptbytype(const jas_image_t *image, jas_image_cmpttype_t ctype);624int jas_image_getcmptbytype(const jas_image_t *image, jas_image_cmpttype_t ctype);
592 625
593/******************************************************************************\626/******************************************************************************\
@@ -597,75 +630,122 @@ int jas_image_getcmptbytype(const jas_image_t *image, jas_image_cmpttype_t ctype · 3 unmodified lines
597/*!630/*!
598@brief Clear the table of image formats.631@brief Clear the table of image formats.
599*/632*/
600JAS_DLLEXPORT633JAS_EXPORT
601void jas_image_clearfmts(void);634void jas_image_clearfmts(void);
602 635
636#if defined(JAS_FOR_INTERNAL_USE_ONLY)
637void jas_image_clearfmts_internal(jas_image_fmtinfo_t *image_fmtinfos,
638 size_t *image_numfmts);
639#endif
640
641/*!
642@brief Get a image format entry by its table index.
643*/
644JAS_EXPORT
645const jas_image_fmtinfo_t *jas_image_getfmtbyind(int index);
646
647/*!
648@brief Get the number of image format table entries.
649*/
650JAS_EXPORT
651int jas_image_getnumfmts(void);
652
653#if 0
654JAS_EXPORT
655int jas_image_delfmtbyid(int id);
656#endif
657
658/*!
659@brief Get the number of image format table entries.
660
661@warning
662This function may be removed in future versions of the library.
663Do not rely on it.
664*/
665JAS_EXPORT
666int jas_image_setfmtenable(int index, int enabled);
667
668#if 0
669// TODO: should this be added?
670JAS_EXPORT
671int jas_image_getfmtindbyname(const char* name);
672#endif
673
603/*!674/*!
604@brief Add entry to table of image formats.675@brief Add entry to table of image formats.
605*/676*/
606JAS_DLLEXPORT677JAS_EXPORT
607int jas_image_addfmt(int id, const char *name, const char *ext,678int jas_image_addfmt(int id, const char *name, const char *ext,
608 const char *desc, const jas_image_fmtops_t *ops);679 const char *desc, const jas_image_fmtops_t *ops);
609 680
681#if defined(JAS_FOR_INTERNAL_USE_ONLY)
682int jas_image_addfmt_internal(jas_image_fmtinfo_t *image_fmtinfos,
683 size_t *image_numfmts, int id, const char *name, const char *ext,
684 const char *desc, const jas_image_fmtops_t *ops);
685#endif
686
610/*!687/*!
611@brief Get the ID for the image format with the specified name.688@brief Get the ID for the image format with the specified name.
612*/689*/
613JAS_ATTRIBUTE_PURE690JAS_ATTRIBUTE_PURE
614JAS_DLLEXPORT691JAS_EXPORT
615int jas_image_strtofmt(const char *s);692int jas_image_strtofmt(const char *s);
616 693
617/*!694/*!
618@brief Get the name of the image format with the specified ID.695@brief Get the name of the image format with the specified ID.
619*/696*/
620JAS_ATTRIBUTE_CONST697JAS_ATTRIBUTE_CONST
621JAS_DLLEXPORT698JAS_EXPORT
622const char *jas_image_fmttostr(int fmt);699const char *jas_image_fmttostr(int fmt);
623 700
624/*!701/*!
625@brief Lookup image format information by the format ID.702@brief Lookup image format information by the format ID.
626*/703*/
627JAS_ATTRIBUTE_CONST704JAS_ATTRIBUTE_CONST
628JAS_DLLEXPORT705JAS_EXPORT
629const jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id);706const jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id);
630 707
631/*!708/*!
632@brief Lookup image format information by the format name.709@brief Lookup image format information by the format name.
633*/710*/
634JAS_ATTRIBUTE_PURE711JAS_ATTRIBUTE_PURE
635JAS_DLLEXPORT712JAS_EXPORT
636const jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name);713const jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name);
637 714
638/*!715/*!
639@brief Guess the format of an image file based on its name.716@brief Guess the format of an image file based on its name.
640*/717*/
641JAS_ATTRIBUTE_PURE718JAS_ATTRIBUTE_PURE
642JAS_DLLEXPORT719JAS_EXPORT
643int jas_image_fmtfromname(const char *filename);720int jas_image_fmtfromname(const char *filename);
644 721
645/*!722/*!
646@brief Get the format of image data in a stream.723@brief Get the format of image data in a stream.
724
725@details
726Note that only enabled codecs are used in determining the image format.
647*/727*/
648JAS_ATTRIBUTE_PURE728JAS_ATTRIBUTE_PURE
649JAS_DLLEXPORT729JAS_EXPORT
650int jas_image_getfmt(jas_stream_t *in);730int jas_image_getfmt(jas_stream_t *in);
651 731
652
653/*!732/*!
654@brief Get the color management profile of an image.733@brief Get the color management profile of an image.
655*/734*/
656#define jas_image_cmprof(image) ((image)->cmprof_)735#define jas_image_cmprof(image) ((image)->cmprof_)
657 736
658/*!737/*!
659@brief ???738@brief
739Test if the sampling of the image is homogeneous.
660*/740*/
661JAS_ATTRIBUTE_PURE741JAS_ATTRIBUTE_PURE
662JAS_DLLEXPORT742JAS_EXPORT
663int jas_image_ishomosamp(const jas_image_t *image);743int jas_image_ishomosamp(const jas_image_t *image);
664 744
665/*!745/*!
666@brief ???746@brief ???
667*/747*/
668JAS_DLLEXPORT748JAS_EXPORT
669int jas_image_sampcmpt(jas_image_t *image, unsigned cmptno, unsigned newcmptno,749int jas_image_sampcmpt(jas_image_t *image, unsigned cmptno, unsigned newcmptno,
670 jas_image_coord_t ho, jas_image_coord_t vo, jas_image_coord_t hs,750 jas_image_coord_t ho, jas_image_coord_t vo, jas_image_coord_t hs,
671 jas_image_coord_t vs, int sgnd, unsigned prec);751 jas_image_coord_t vs, int sgnd, unsigned prec);
@@ -673,14 +753,15 @@ int jas_image_sampcmpt(jas_image_t *image, unsigned cmptno, unsigned newcmptno, · 1 unmodified line
673/*!753/*!
674@brief Write sample data in a component of an image.754@brief Write sample data in a component of an image.
675*/755*/
676JAS_DLLEXPORT int jas_image_writecmpt2(jas_image_t *image, unsigned cmptno, jas_image_coord_t x,756JAS_EXPORT
677 jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height,757int jas_image_writecmpt2(jas_image_t *image, unsigned cmptno,
678 const long *buf);758 jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,
759 jas_image_coord_t height, const long *buf);
679 760
680/*!761/*!
681@brief Read sample data in a component of an image.762@brief Read sample data in a component of an image.
682*/763*/
683JAS_DLLEXPORT764JAS_EXPORT
684int jas_image_readcmpt2(jas_image_t *image, unsigned cmptno,765int jas_image_readcmpt2(jas_image_t *image, unsigned cmptno,
685 jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,766 jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width,
686 jas_image_coord_t height, long *buf);767 jas_image_coord_t height, long *buf);
@@ -693,8 +774,15 @@ int jas_image_readcmpt2(jas_image_t *image, unsigned cmptno, · 6 unmodified lines
693/*!774/*!
694@brief Change the color space for an image.775@brief Change the color space for an image.
695*/776*/
696JAS_DLLEXPORT jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmprof_t *outprof,777JAS_EXPORT
697 jas_cmxform_intent_t intent);778jas_image_t *jas_image_chclrspc(jas_image_t *image,
779 const jas_cmprof_t *outprof, jas_cmxform_intent_t intent);
780
781/*!
782@brief Dump the information for an image (for debugging).
783*/
784JAS_EXPORT
785int jas_image_dump(jas_image_t *image, FILE *out);
698 786
699/******************************************************************************\787/******************************************************************************\
700* Image format-dependent operations.788* Image format-dependent operations.
@@ -702,58 +790,92 @@ JAS_DLLEXPORT jas_image_t *jas_image_chclrspc(jas_image_t *image, const jas_cmpr · 1 unmodified line
702 790
703#if defined(JAS_INCLUDE_JPG_CODEC)791#if defined(JAS_INCLUDE_JPG_CODEC)
704/* Format-dependent operations for JPG support. */792/* Format-dependent operations for JPG support. */
705JAS_DLLEXPORT jas_image_t *jpg_decode(jas_stream_t *in, const char *optstr);793//JAS_EXPORT
706JAS_DLLEXPORT int jpg_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);794jas_image_t *jpg_decode(jas_stream_t *in, const char *optstr);
707JAS_DLLEXPORT int jpg_validate(jas_stream_t *in);795//JAS_EXPORT
796int jpg_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);
797//JAS_EXPORT
798int jpg_validate(jas_stream_t *in);
799#endif
800
801#if defined(JAS_INCLUDE_HEIC_CODEC)
802/* Format-dependent operations for HEIC support. */
803//JAS_EXPORT
804jas_image_t *jas_heic_decode(jas_stream_t *in, const char *optstr);
805//JAS_EXPORT
806int jas_heic_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);
807//JAS_EXPORT
808int jas_heic_validate(jas_stream_t *in);
708#endif809#endif
709 810
710#if defined(JAS_INCLUDE_MIF_CODEC)811#if defined(JAS_INCLUDE_MIF_CODEC)
711/* Format-dependent operations for MIF support. */812/* Format-dependent operations for MIF support. */
712JAS_DLLEXPORT jas_image_t *mif_decode(jas_stream_t *in, const char *optstr);813//JAS_EXPORT
713JAS_DLLEXPORT int mif_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);814jas_image_t *mif_decode(jas_stream_t *in, const char *optstr);
714JAS_DLLEXPORT int mif_validate(jas_stream_t *in);815//JAS_EXPORT
816int mif_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);
817//JAS_EXPORT
818int mif_validate(jas_stream_t *in);
715#endif819#endif
716 820
717#if defined(JAS_INCLUDE_PNM_CODEC)821#if defined(JAS_INCLUDE_PNM_CODEC)
718/* Format-dependent operations for PNM support. */822/* Format-dependent operations for PNM support. */
719JAS_DLLEXPORT jas_image_t *pnm_decode(jas_stream_t *in, const char *optstr);823//JAS_EXPORT
720JAS_DLLEXPORT int pnm_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);824jas_image_t *pnm_decode(jas_stream_t *in, const char *optstr);
721JAS_DLLEXPORT int pnm_validate(jas_stream_t *in);825//JAS_EXPORT
826int pnm_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);
827//JAS_EXPORT
828int pnm_validate(jas_stream_t *in);
722#endif829#endif
723 830
724#if defined(JAS_INCLUDE_RAS_CODEC)831#if defined(JAS_INCLUDE_RAS_CODEC)
725/* Format-dependent operations for Sun Rasterfile support. */832/* Format-dependent operations for Sun Rasterfile support. */
726JAS_DLLEXPORT jas_image_t *ras_decode(jas_stream_t *in, const char *optstr);833//JAS_EXPORT
727JAS_DLLEXPORT int ras_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);834jas_image_t *ras_decode(jas_stream_t *in, const char *optstr);
728JAS_DLLEXPORT int ras_validate(jas_stream_t *in);835//JAS_EXPORT
836int ras_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);
837//JAS_EXPORT
838int ras_validate(jas_stream_t *in);
729#endif839#endif
730 840
731#if defined(JAS_INCLUDE_BMP_CODEC)841#if defined(JAS_INCLUDE_BMP_CODEC)
732/* Format-dependent operations for BMP support. */842/* Format-dependent operations for BMP support. */
733JAS_DLLEXPORT jas_image_t *bmp_decode(jas_stream_t *in, const char *optstr);843//JAS_EXPORT
734JAS_DLLEXPORT int bmp_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);844jas_image_t *bmp_decode(jas_stream_t *in, const char *optstr);
735JAS_DLLEXPORT int bmp_validate(jas_stream_t *in);845//JAS_EXPORT
846int bmp_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);
847//JAS_EXPORT
848int bmp_validate(jas_stream_t *in);
736#endif849#endif
737 850
738#if defined(JAS_INCLUDE_JP2_CODEC)851#if defined(JAS_INCLUDE_JP2_CODEC)
739/* Format-dependent operations for JP2 support. */852/* Format-dependent operations for JP2 support. */
740JAS_DLLEXPORT jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr);853//JAS_EXPORT
741JAS_DLLEXPORT int jp2_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);854jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr);
742JAS_DLLEXPORT int jp2_validate(jas_stream_t *in);855//JAS_EXPORT
856int jp2_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);
857//JAS_EXPORT
858int jp2_validate(jas_stream_t *in);
743#endif859#endif
744 860
745#if defined(JAS_INCLUDE_JPC_CODEC)861#if defined(JAS_INCLUDE_JPC_CODEC)
746/* Format-dependent operations for JPEG-2000 code stream support. */862/* Format-dependent operations for JPEG-2000 code stream support. */
747JAS_DLLEXPORT jas_image_t *jpc_decode(jas_stream_t *in, const char *optstr);863//JAS_EXPORT
748JAS_DLLEXPORT int jpc_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);864jas_image_t *jpc_decode(jas_stream_t *in, const char *optstr);
749JAS_DLLEXPORT int jpc_validate(jas_stream_t *in);865//JAS_EXPORT
866int jpc_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);
867//JAS_EXPORT
868int jpc_validate(jas_stream_t *in);
750#endif869#endif
751 870
752#if defined(JAS_INCLUDE_PGX_CODEC)871#if defined(JAS_INCLUDE_PGX_CODEC)
753/* Format-dependent operations for PGX support. */872/* Format-dependent operations for PGX support. */
754JAS_DLLEXPORT jas_image_t *pgx_decode(jas_stream_t *in, const char *optstr);873//JAS_EXPORT
755JAS_DLLEXPORT int pgx_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);874jas_image_t *pgx_decode(jas_stream_t *in, const char *optstr);
756JAS_DLLEXPORT int pgx_validate(jas_stream_t *in);875//JAS_EXPORT
876int pgx_encode(jas_image_t *image, jas_stream_t *out, const char *optstr);
877//JAS_EXPORT
878int pgx_validate(jas_stream_t *in);
757#endif879#endif
758 880
759/*!881/*!
jasper/jas_init.h+391−10
@@ -70,42 +70,423 @@ · 69 unmodified lines
70/* The configuration header file should be included first. */70/* The configuration header file should be included first. */
71#include <jasper/jas_config.h>71#include <jasper/jas_config.h>
72 72
73#include "jasper/jas_malloc.h"
74#include "jasper/jas_image.h"
75#include "jasper/jas_log.h"
76
73#ifdef __cplusplus77#ifdef __cplusplus
74extern "C" {78extern "C" {
75#endif79#endif
76 80
77/*!81/*!
78 * @addtogroup init82 * @addtogroup module_init
79 * @{83 * @{
80 */84 */
81 85
86#if defined(JAS_FOR_INTERNAL_USE_ONLY)
87/*
88Per-thread library context.
89*/
90typedef struct {
91
92 /*
93 The level of debugging checks/output enabled by the library.
94 A larger value corresponds to a greater level of debugging checks/output.
95 */
96 int debug_level;
97
98 /*
99 The function used to output error/warning/informational messages.
100 int (*vlogmsgf)(jas_logtype_t type, const char *format, va_list ap);
101 */
102 jas_vlogmsgf_t *vlogmsgf;
103
104 /*
105 The image format information to be used to populate the image format
106 table.
107 */
108 size_t image_numfmts;
109 jas_image_fmtinfo_t image_fmtinfos[JAS_IMAGE_MAXFMTS];
110
111 /* The maximum number of samples allowable in an image to be decoded. */
112 size_t dec_default_max_samples;
113
114} jas_ctx_t;
115#endif
116
117/*!
118@brief
119An opaque handle type used to represent a JasPer library context.
120*/
121typedef void *jas_context_t;
122
123/******************************************************************************\
124* Library Run-Time Configuration.
125\******************************************************************************/
126
127/*!
128@brief
129Configure the JasPer library with the default configuration settings.
130
131@details
132This function configures the JasPer library with the default configuration
133settings.
134These settings may be change via the @c jas_conf_* family of function
135prior to invoking jas_init_library().
136
137@warning
138Configuration, initialization, and cleanup of the library must be performed
139on the same thread.
140*/
141JAS_EXPORT
142void jas_conf_clear(void);
143
144/*!
145@brief Set the multithreading flag for the library.
146
147@details
148*/
149JAS_EXPORT
150void jas_conf_set_multithread(int multithread);
151
152/*!
153@brief Set the memory allocator to be used by the library.
154
155@details
156The object referenced by @c allocator must have a live at least
157until jas_cleanup() is invoked.
158How the memory in which @c *allocator reside is allocated is the
159responsibility of the caller.
160*/
161JAS_EXPORT
162void jas_conf_set_allocator(jas_allocator_t *allocator);
163
164/*!
165@brief Set the initial debug level for the library.
166
167@details
168*/
169JAS_EXPORT
170void jas_conf_set_debug_level(int debug_level);
171
172/*!
173@brief
174Set the maximum amount of memory that can be used by the library
175(assuming the allocator wrapper is not disabled).
176
177@details
178
179@warning
180It is strongly recommended that the memory usage limit not be set to an
181excessively large value, as this poses security risks (e.g., decoding a
182malicious image file could exhaust all virtual memory and effectively
183crash the system).
184*/
185JAS_EXPORT
186void jas_conf_set_max_mem_usage(size_t max_mem);
187
188/*!
189@brief
190Set the default value for the maximum number of samples that is
191allowed in an image to be decoded.
192
193@details
194*/
195JAS_EXPORT
196void jas_conf_set_dec_default_max_samples(size_t max_samples);
197
198/*!
199@brief
200Set the function used by the library to output error, warning, and
201informational messages.
202
203@details
204*/
205JAS_EXPORT
206void jas_conf_set_vlogmsgf(jas_vlogmsgf_t *func);
207
82/******************************************************************************\208/******************************************************************************\
83* Functions.209* Library Initialization and Cleanup.
84\******************************************************************************/210\******************************************************************************/
85 211
86/*!212/*!
87@brief Initialize the JasPer library.213@brief
214Initialize the JasPer library with the current configuration settings.
88 215
89@details216@details
90This function must be called before any other code in the JasPer library217The library must be configured by invoking the jas_conf_clear() function
91is invoked.218prior to calling jas_init_library().
92This function registers the codecs that are enabled by default.
93 219
94@returns220@returns
95If successful, zero is returned; otherwise, a nonzero value is returned.221If the initialization of the library is successful, zero is returned;
222otherwise, a nonzero value is returned.
223
224@warning
225The jas_init_library() function does NOT synchronize with the
226jas_conf_clear() function.
227Configuration, initialization, and cleanup of the library must be
228performed on the same thread.
229*/
230JAS_EXPORT
231int jas_init_library(void);
232
233/*!
234@brief
235Perform clean up for the JasPer library.
236
237@details
238At the point when this function is called, all threads that have called
239jas_init_thread() must have called jas_cleanup_thread().
240
241@returns
242If the operation is successful, zero is returned.
243Otherwise, a nonzero value is returned.
244*/
245JAS_EXPORT
246int jas_cleanup_library(void);
247
248/******************************************************************************\
249* Thread Initialization and Cleanup.
250\******************************************************************************/
251
252/*!
253@brief
254Perform per-thread initialization for the JasPer library.
255
256@details
257The library must be initialized by invoking the jas_init_library() function
258prior to calling jas_init_thread().
259
260@warning
261The jas_init_thread() function can only be invoked in a single thread
262unless the run-time configuration has enabled multithreading via
263jas_set_multithread().
96*/264*/
97JAS_DLLEXPORT265JAS_EXPORT
266int jas_init_thread(void);
267
268/*!
269@brief
270Perform per-thread cleanup for the JasPer library.
271
272@details
273*/
274JAS_EXPORT
275int jas_cleanup_thread(void);
276
277/******************************************************************************\
278* Legacy Initialization and Cleanup Functions.
279\******************************************************************************/
280
281/*!
282@brief
283Configure and initialize the JasPer library using the default
284configuration settings.
285
286@details
287The jas_init() function initializes the JasPer library.
288The library must be initialized before most code in the library can be used.
289
290The jas_init() function exists only for reasons of backward compatibility
291with earlier versions of the library.
292It is recommended that this function not be used.
293Instead, the jas_conf_clear() and jas_init_library() functions should be used
294to configure and initialize the library.
295
296@returns
297If the library is successfully initialized, zero is returned;
298otherwise, a nonzero value is returned.
299
300@warning
301Configuration, initialization, and cleanup of the library must be performed
302on the same thread.
303
304@deprecated
305This function is deprecated.
306*/
307JAS_EXPORT
98int jas_init(void);308int jas_init(void);
99 309
100/*!310/*!
101@brief Perform any clean up for the JasPer library.311@brief
312Perform any clean up for the JasPer library.
102 313
103@details314@details
104This function performs any clean up for the JasPer library.315This function performs any clean up for the JasPer library.
316
317@warning
318Configuration, initialization, and cleanup of the library must be performed
319on the same thread.
320
321@deprecated
322This function is deprecated.
105*/323*/
106JAS_DLLEXPORT324JAS_EXPORT
107void jas_cleanup(void);325void jas_cleanup(void);
108 326
327/******************************************************************************\
328* Context Management
329\******************************************************************************/
330
331/*!
332@brief
333Create a context.
334
335@details
336*/
337JAS_EXPORT
338jas_context_t jas_context_create(void);
339
340/*!
341@brief
342Destroy a context.
343
344@details
345The context being destroyed must not be the current context.
346*/
347JAS_EXPORT
348void jas_context_destroy(jas_context_t context);
349
350/*!
351@brief
352Get the current context for the calling thread.
353
354@details
355*/
356JAS_EXPORT
357jas_context_t jas_get_default_context(void);
358
359/*!
360@brief
361Get the current context for the calling thread.
362
363@details
364*/
365JAS_EXPORT
366jas_context_t jas_get_context(void);
367
368/*!
369@brief
370Set the current context for the calling thread.
371
372@details
373*/
374JAS_EXPORT
375void jas_set_context(jas_context_t context);
376
377/******************************************************************************\
378* Getting/Setting Context Properties
379\******************************************************************************/
380
381/* This function is only for internal use by the library. */
382JAS_EXPORT
383int jas_get_debug_level_internal(void);
384
385/* This function is only for internal use by the library. */
386JAS_EXPORT
387size_t jas_get_dec_default_max_samples_internal(void);
388
389/* This function is only for internal use by the library. */
390JAS_EXPORT
391jas_vlogmsgf_t *jas_get_vlogmsgf_internal(void);
392
393#if defined(JAS_FOR_INTERNAL_USE_ONLY)
394#if defined(JAS_HAVE_THREAD_LOCAL)
395extern _Thread_local jas_ctx_t *jas_cur_ctx;
396#endif
397
398/* This function is only for internal use by the library. */
399jas_ctx_t *jas_get_ctx_internal(void);
400
401/* This function is only for internal use by the library. */
402static inline jas_ctx_t *jas_get_ctx(void)
403{
404#if defined(JAS_HAVE_THREAD_LOCAL)
405 return jas_cur_ctx ? jas_cur_ctx : jas_get_ctx_internal();
406#else
407 return JAS_CAST(jas_ctx_t *, jas_get_ctx_internal());
408#endif
409}
410#endif
411
412/*!
413@brief
414Set the debug level for a particular context.
415
416@details
417*/
418JAS_EXPORT
419void jas_set_debug_level(int debug_level);
420
421/*!
422@brief
423Get the debug level for a particular context.
424
425@details
426*/
427static inline int jas_get_debug_level(void)
428{
429#if defined(JAS_FOR_INTERNAL_USE_ONLY)
430 jas_ctx_t *ctx = jas_get_ctx();
431 return ctx->debug_level;
432#else
433 return jas_get_debug_level_internal();
434#endif
435}
436
437/*!
438@brief
439Set the default maximum number of samples that a decoder is permitted to
440process.
441
442@details
443*/
444JAS_EXPORT
445void jas_set_dec_default_max_samples(size_t max_samples);
446
447/*!
448@brief
449Get the default maximum number of samples that a decoder is permitted to
450process.
451
452@details
453*/
454static inline size_t jas_get_dec_default_max_samples(void)
455{
456#if defined(JAS_FOR_INTERNAL_USE_ONLY)
457 jas_ctx_t *ctx = jas_get_ctx();
458 return ctx->dec_default_max_samples;
459#else
460 return jas_get_dec_default_max_samples_internal();
461#endif
462}
463
464/*!
465@brief
466Set the function to be used for log messages.
467
468@details
469*/
470JAS_EXPORT
471void jas_set_vlogmsgf(jas_vlogmsgf_t *func);
472
473/*!
474@brief
475Get the function to be used for log messages.
476
477@details
478*/
479static inline
480jas_vlogmsgf_t *jas_get_vlogmsgf(void)
481{
482#if defined(JAS_FOR_INTERNAL_USE_ONLY)
483 jas_ctx_t *ctx = jas_get_ctx();
484 return ctx->vlogmsgf;
485#else
486 return jas_get_vlogmsgf_internal();
487#endif
488}
489
109/*!490/*!
110 * @}491 * @}
111 */492 */
jasper/jas_log.h+168−0
@@ -0,0 +1,168 @@
1/*
2 * Copyright (c) 2001-2002 Michael David Adams.
3 * All rights reserved.
4 */
5
6/* __START_OF_JASPER_LICENSE__
7 *
8 * JasPer License Version 2.0
9 *
10 * Copyright (c) 2001-2006 Michael David Adams
11 * Copyright (c) 1999-2000 Image Power, Inc.
12 * Copyright (c) 1999-2000 The University of British Columbia
13 *
14 * All rights reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person (the
17 * "User") obtaining a copy of this software and associated documentation
18 * files (the "Software"), to deal in the Software without restriction,
19 * including without limitation the rights to use, copy, modify, merge,
20 * publish, distribute, and/or sell copies of the Software, and to permit
21 * persons to whom the Software is furnished to do so, subject to the
22 * following conditions:
23 *
24 * 1. The above copyright notices and this permission notice (which
25 * includes the disclaimer below) shall be included in all copies or
26 * substantial portions of the Software.
27 *
28 * 2. The name of a copyright holder shall not be used to endorse or
29 * promote products derived from the Software without specific prior
30 * written permission.
31 *
32 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
33 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
34 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
35 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
37 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
38 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
39 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
40 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
41 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
42 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
43 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
44 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
45 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
46 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
47 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
48 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
49 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
50 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
51 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
52 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
53 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
54 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
55 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
56 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
57 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
58 *
59 * __END_OF_JASPER_LICENSE__
60 */
61
62/*!
63 * @file jas_log.h
64 * @brief JasPer Logging Functionality
65 */
66
67#ifndef JAS_LOG_H
68#define JAS_LOG_H
69
70/******************************************************************************\
71* Includes.
72\******************************************************************************/
73
74/* The configuration header file should be included first. */
75#include <jasper/jas_config.h>
76
77#ifdef __cplusplus
78extern "C" {
79#endif
80
81/*!
82 * @addtogroup module_log
83 * @{
84 */
85
86/******************************************************************************\
87* Macros and functions.
88\******************************************************************************/
89
90/*! Log type class for unclassified messages. */
91#define JAS_LOGTYPE_CLASS_NULL 0
92/*! Log type class for errors. */
93#define JAS_LOGTYPE_CLASS_ERROR 1
94/*! Log type class for warnings. */
95#define JAS_LOGTYPE_CLASS_WARN 2
96/*! Log type class for informational messages. */
97#define JAS_LOGTYPE_CLASS_INFO 3
98/*! Log type class for debugging messages. */
99#define JAS_LOGTYPE_CLASS_DEBUG 4
100#define JAS_LOGTYPE_NUM_CLASSES 5
101
102#define JAS_LOGTYPE_MAX_PRIORITY 16384
103
104// NOTE: without the @struct, jas_logtype_t autolinks are not generated
105/*!
106@struct jas_logtype_t
107@brief Type used for the log type.
108*/
109typedef unsigned int jas_logtype_t;
110
111/*!
112@brief Type used for formatted message logging function.
113*/
114typedef int (jas_vlogmsgf_t)(jas_logtype_t, const char *, va_list);
115
116/*!
117@brief Create an instance of a logtype.
118*/
119static inline jas_logtype_t jas_logtype_init(int clas, int priority)
120{
121 assert(clas >= 0 && clas < JAS_LOGTYPE_NUM_CLASSES);
122 assert(priority >= 0 && priority <= JAS_LOGTYPE_MAX_PRIORITY);
123 return (clas & 0xf) | (priority << 4);
124}
125
126/*!
127@brief Get the class of a logtype.
128*/
129static inline int jas_logtype_getclass(jas_logtype_t type)
130{
131 return type & 0xf;
132}
133
134/*!
135@brief Get the priority of a logtype.
136*/
137static inline int jas_logtype_getpriority(jas_logtype_t type)
138{
139 return type >> 4;
140}
141
142/*!
143@brief Print formatted log message.
144*/
145JAS_EXPORT
146int jas_vlogmsgf(jas_logtype_t type, const char *fmt, va_list ap);
147
148/*!
149@brief Output a log message to standard error.
150*/
151JAS_EXPORT
152int jas_vlogmsgf_stderr(jas_logtype_t type, const char *fmt, va_list ap);
153
154/*!
155@brief Output a log message to nowhere (i.e., discard the message).
156*/
157JAS_EXPORT
158int jas_vlogmsgf_discard(jas_logtype_t type, const char *fmt, va_list ap);
159
160/*!
161 * @}
162 */
163
164#ifdef __cplusplus
165}
166#endif
167
168#endif
jasper/jas_malloc.h+272−7
@@ -77,17 +77,282 @@ · 76 unmodified lines
77/* The configuration header file should be included first. */77/* The configuration header file should be included first. */
78#include <jasper/jas_config.h>78#include <jasper/jas_config.h>
79 79
80#include <jasper/jas_types.h>
81#include <jasper/jas_thread.h>
82
80#ifdef __cplusplus83#ifdef __cplusplus
81extern "C" {84extern "C" {
82#endif85#endif
83 86
84#define jas_malloc malloc87/*!
85#define jas_free free88 * @addtogroup module_alloc
86#define jas_realloc realloc89 * @{
87#define jas_calloc calloc90 */
88#define jas_alloc2(ne, esz) malloc(ne*esz)91
89#define jas_alloc3(na, asz, esz) malloc(na*asz*esz)92/******************************************************************************\
90#define jas_realloc2(p, ne, esz) realloc(p, ne*esz)93* Types.
94\******************************************************************************/
95
96/*!
97@brief A memory allocator.
98*/
99typedef struct jas_allocator_s {
100
101 /*!
102 Function to clean up the allocator when no longer needed.
103 The allocator cannot be used after the clean-up operation is performed.
104 This function pointer may be null, in which case the clean-up operation
105 is treated as a no-op.
106 */
107 void (*cleanup)(struct jas_allocator_s *allocator);
108
109 /*!
110 Function to allocate memory.
111 This function should have behavior similar to malloc.
112 */
113 void *(*alloc)(struct jas_allocator_s *allocator, size_t size);
114
115 /*!
116 Function to deallocate memory.
117 This function should have behavior similar to free.
118 */
119 void (*free)(struct jas_allocator_s *allocator, void *pointer);
120
121 /*!
122 Function to reallocate memory.
123 This function should have behavior similar to realloc.
124 */
125 void *(*realloc)(struct jas_allocator_s *allocator, void *pointer,
126 size_t new_size);
127
128 /*! For future use. */
129 void (*(reserved[4]))(void);
130
131} jas_allocator_t;
132
133/*!
134@brief The standard library allocator (i.e., a wrapper for malloc and friends).
135
136@details
137Essentially, jas_std_allocator_t can be thought of as having an inheritance
138relationship with jas_allocator_t.
139In particular, jas_std_allocator_t is derived from jas_allocator_t.
140*/
141typedef struct {
142
143 /* The base class. */
144 jas_allocator_t base;
145
146} jas_std_allocator_t;
147
148#if defined(JAS_FOR_INTERNAL_USE_ONLY)
149/*
150The allocator wrapper type.
151This type is an allocator that adds memory usage tracking to another
152allocator.
153The allocator wrapper does not directly perform memory allocation itself.
154Instead, it delegate to another allocator.
155*/
156typedef struct {
157
158 /* The base class. */
159 jas_allocator_t base;
160
161 /* The delegated-to allocator. */
162 jas_allocator_t *delegate;
163
164 /* The maximum amount of memory that can be used by the allocator. */
165 size_t max_mem;
166
167 /* The current amount of memory in use by the allocator. */
168 size_t mem;
169
170#if defined(JAS_THREADS)
171 /* A mutex for synchronized access to the allocator. */
172 jas_mutex_t mutex;
173#endif
174
175} jas_basic_allocator_t;
176#endif
177
178/******************************************************************************\
179* Data.
180\******************************************************************************/
181
182#if defined(JAS_FOR_INTERNAL_USE_ONLY)
183extern jas_allocator_t *jas_allocator;
184extern jas_std_allocator_t jas_std_allocator;
185extern jas_basic_allocator_t jas_basic_allocator;
186#endif
187
188/******************************************************************************\
189* Functions.
190\******************************************************************************/
191
192/*!
193@brief
194Allocate memory.
195
196@details
197This function has an identical behavior as malloc (from the C standard
198library), except that a zero-sized allocation returns a non-null pointer
199(assuming no out-of-memory error occurs).
200*/
201JAS_EXPORT
202void *jas_malloc(size_t size);
203
204/*!
205@brief
206Free memory.
207
208@details
209This function has an identical behavior as free (from the C standard library).
210*/
211JAS_EXPORT
212void jas_free(void *ptr);
213
214/*!
215@brief
216Resize a block of allocated memory.
217
218@details
219This function has an identical behavior as realloc (from the C standard
220library).
221*/
222JAS_EXPORT
223void *jas_realloc(void *ptr, size_t size);
224
225/*!
226@brief
227Allocate a block of memory and initialize the contents to zero.
228
229@details
230This function has an identical behavior as calloc (from the C standard
231library).
232*/
233JAS_EXPORT
234void *jas_calloc(size_t num_elements, size_t element_size);
235
236/*!
237@brief
238Allocate array (with overflow checking).
239*/
240JAS_EXPORT
241void *jas_alloc2(size_t num_elements, size_t element_size);
242
243/*!
244@brief
245Allocate array of arrays (with overflow checking).
246*/
247JAS_EXPORT
248void *jas_alloc3(size_t num_arrays, size_t array_size, size_t element_size);
249
250/*!
251@brief
252Resize a block of allocated memory (with overflow checking).
253*/
254JAS_EXPORT
255void *jas_realloc2(void *ptr, size_t num_elements, size_t element_size);
256
257/*!
258@brief
259Set the maximum memory usage allowed by the allocator wrapper.
260
261@param max_mem
262The maximum amount of memory (in bytes) that the allocator can use.
263
264
265@details
266This function sets the maximum amount of memory (in bytes) that the
267allocator wrapper is permitted to use to @c max_mem.
268If @c max_mem is zero, no limit is imposed on the amount of memory used by
269allocator.
270This function can only be called if the use of the allocator wrapper
271is enabled.
272Calling this function if the allocator wrapper is not enabled results
273in undefined behavior.
274The limit on the amount of memory that the allocator can use should
275never be set to a value less than the amount of memory currently being
276used by the allocator (as doing so results in undefined behavior).
277*/
278JAS_EXPORT
279void jas_set_max_mem_usage(size_t max_mem);
280
281/*!
282@brief
283Get the current memory usage from the allocator wrapper.
284
285@details
286This function queries the amount of memory currently in use by the allocator
287wrapper.
288This function can only be called if the use of the allocator wrapper
289is enabled.
290Calling this function if the allocator wrapper is not enabled results
291in undefined behavior.
292*/
293JAS_EXPORT
294size_t jas_get_mem_usage(void);
295
296/*!
297@brief
298Initialize a memory allocator that uses malloc and related functions
299for managing memory.
300
301@param allocator
302A pointer to the storage in memory that will hold the state associated
303with the allocator.
304
305@details
306The object referenced by @c allocator must have a lifetime that extends
307until @c jas_allocator_cleanup is called for the allocator.
308*/
309JAS_EXPORT
310void jas_std_allocator_init(jas_std_allocator_t *allocator);
311
312/*!
313@brief
314Clean up an allocator that is no longer needed.
315
316@details
317This function cleans up an allocator, releasing any resources associated
318with the allocator.
319After clean up is performed, the allocator can no longer be used.
320*/
321JAS_EXPORT
322void jas_allocator_cleanup(jas_allocator_t *allocator);
323
324#if defined(JAS_FOR_INTERNAL_USE_ONLY)
325
326/* This function is for internal library use only. */
327void jas_set_allocator(jas_allocator_t* allocator);
328
329/* This function is for internal library use only. */
330void jas_basic_allocator_init(jas_basic_allocator_t *allocator,
331 jas_allocator_t *delegate, size_t max_mem);
332
333#endif
334
335/*!
336@brief
337Get the total amount of memory available on the system.
338
339@details
340This function may be called prior to the library being initialized.
341In fact, this function may be useful for determining a reasonable value
342for the memory limit setting to be used during (run-time) library
343configuration.
344
345@returns
346The total amount of memory available (in bytes) is returned, if this can
347be determined.
348Otherwise, zero is returned.
349*/
350JAS_EXPORT
351size_t jas_get_total_mem_size(void);
352
353/*!
354 * @}
355 */
91 356
92#ifdef __cplusplus357#ifdef __cplusplus
93}358}
jasper/jas_math.h+401−32
@@ -75,6 +75,8 @@ · 74 unmodified lines
75 75
76/* The configuration header file should be included first. */76/* The configuration header file should be included first. */
77#include <jasper/jas_config.h>77#include <jasper/jas_config.h>
78
79#include <jasper/jas_compiler.h>
78#include <jasper/jas_types.h>80#include <jasper/jas_types.h>
79 81
80#ifdef __cplusplus82#ifdef __cplusplus
@@ -109,6 +111,12 @@ extern "C" { · 28 unmodified lines
109 set to one. */111 set to one. */
110#define JAS_ONES(n) \112#define JAS_ONES(n) \
111 ((1 << (n)) - 1)113 ((1 << (n)) - 1)
114#if 0
115#define JAS_ONES_X(type, n) \
116 ((JAS_CAST(type, 1) << (n)) - 1)
117#endif
118#define JAS_POW2_X(type, n) \
119 (JAS_CAST(type, 1) << (n))
112 120
113/******************************************************************************\121/******************************************************************************\
114*122*
@@ -122,78 +130,78 @@ extern "C" { · 7 unmodified lines
122#endif130#endif
123 131
124JAS_ATTRIBUTE_CONST132JAS_ATTRIBUTE_CONST
125JAS_ATTRIBUTE_DISABLE_USAN133JAS_ATTRIBUTE_DISABLE_UBSAN
126inline static int jas_int_asr(int x, unsigned n)134inline static int jas_int_asr(int x, unsigned n)
127{135{
128 // Ensure that the shift of a negative value appears to behave as a136 // Ensure that the shift of a negative value appears to behave as a
129 // signed arithmetic shift.137 // signed arithmetic shift.
130 assert(((-1) >> 1) == -1);138 assert(((-1) >> 1) == -1);
131 // The behavior is undefined when x is negative. */139 // The behavior is undefined when x is negative.
132 // We tacitly assume the behavior is equivalent to a signed140 // We tacitly assume the behavior is equivalent to a signed
133 // arithmetic right shift.141 // arithmetic right shift.
134 return x >> n;142 return x >> n;
135}143}
136 144
137JAS_ATTRIBUTE_CONST145JAS_ATTRIBUTE_CONST
138JAS_ATTRIBUTE_DISABLE_USAN146JAS_ATTRIBUTE_DISABLE_UBSAN
139inline static int jas_int_asl(int x, unsigned n)147inline static int jas_int_asl(int x, unsigned n)
140{148{
141 // Ensure that the shift of a negative value appears to behave as a149 // Ensure that the shift of a negative value appears to behave as a
142 // signed arithmetic shift.150 // signed arithmetic shift.
143 assert(((-1) << 1) == -2);151 assert(((-1) << 1) == -2);
144 // The behavior is undefined when x is negative. */152 // The behavior is undefined when x is negative.
145 // We tacitly assume the behavior is equivalent to a signed153 // We tacitly assume the behavior is equivalent to a signed
146 // arithmetic left shift.154 // arithmetic left shift.
147 return x << n;155 return x << n;
148}156}
149 157
150JAS_ATTRIBUTE_CONST158JAS_ATTRIBUTE_CONST
151JAS_ATTRIBUTE_DISABLE_USAN159JAS_ATTRIBUTE_DISABLE_UBSAN
152inline static int_least32_t jas_least32_asr(int_least32_t x, unsigned n)160inline static int_least32_t jas_least32_asr(int_least32_t x, unsigned n)
153{161{
154 // Ensure that the shift of a negative value appears to behave as a162 // Ensure that the shift of a negative value appears to behave as a
155 // signed arithmetic shift.163 // signed arithmetic shift.
156 assert(((JAS_CAST(int_least32_t, -1)) >> 1) == JAS_CAST(int_least32_t, -1));164 assert(((JAS_CAST(int_least32_t, -1)) >> 1) == JAS_CAST(int_least32_t, -1));
157 // The behavior is undefined when x is negative. */165 // The behavior is undefined when x is negative.
158 // We tacitly assume the behavior is equivalent to a signed166 // We tacitly assume the behavior is equivalent to a signed
159 // arithmetic right shift.167 // arithmetic right shift.
160 return x >> n;168 return x >> n;
161}169}
162 170
163JAS_ATTRIBUTE_CONST171JAS_ATTRIBUTE_CONST
164JAS_ATTRIBUTE_DISABLE_USAN172JAS_ATTRIBUTE_DISABLE_UBSAN
165inline static int_least32_t jas_least32_asl(int_least32_t x, unsigned n)173inline static int_least32_t jas_least32_asl(int_least32_t x, unsigned n)
166{174{
167 // Ensure that the shift of a negative value appears to behave as a175 // Ensure that the shift of a negative value appears to behave as a
168 // signed arithmetic shift.176 // signed arithmetic shift.
169 assert(((JAS_CAST(int_least32_t, -1)) << 1) == JAS_CAST(int_least32_t, -2));177 assert(((JAS_CAST(int_least32_t, -1)) << 1) == JAS_CAST(int_least32_t, -2));
170 // The behavior is undefined when x is negative. */178 // The behavior is undefined when x is negative.
171 // We tacitly assume the behavior is equivalent to a signed179 // We tacitly assume the behavior is equivalent to a signed
172 // arithmetic left shift.180 // arithmetic left shift.
173 return x << n;181 return x << n;
174}182}
175 183
176JAS_ATTRIBUTE_CONST184JAS_ATTRIBUTE_CONST
177JAS_ATTRIBUTE_DISABLE_USAN185JAS_ATTRIBUTE_DISABLE_UBSAN
178inline static int_fast32_t jas_fast32_asr(int_fast32_t x, unsigned n)186inline static int_fast32_t jas_fast32_asr(int_fast32_t x, unsigned n)
179{187{
180 // Ensure that the shift of a negative value appears to behave as a188 // Ensure that the shift of a negative value appears to behave as a
181 // signed arithmetic shift.189 // signed arithmetic shift.
182 assert(((JAS_CAST(int_fast32_t, -1)) >> 1) == JAS_CAST(int_fast32_t, -1));190 assert(((JAS_CAST(int_fast32_t, -1)) >> 1) == JAS_CAST(int_fast32_t, -1));
183 // The behavior is undefined when x is negative. */191 // The behavior is undefined when x is negative.
184 // We tacitly assume the behavior is equivalent to a signed192 // We tacitly assume the behavior is equivalent to a signed
185 // arithmetic right shift.193 // arithmetic right shift.
186 return x >> n;194 return x >> n;
187}195}
188 196
189JAS_ATTRIBUTE_CONST197JAS_ATTRIBUTE_CONST
190JAS_ATTRIBUTE_DISABLE_USAN198JAS_ATTRIBUTE_DISABLE_UBSAN
191inline static int_fast32_t jas_fast32_asl(int_fast32_t x, unsigned n)199inline static int_fast32_t jas_fast32_asl(int_fast32_t x, unsigned n)
192{200{
193 // Ensure that the shift of a negative value appears to behave as a201 // Ensure that the shift of a negative value appears to behave as a
194 // signed arithmetic shift.202 // signed arithmetic shift.
195 assert(((JAS_CAST(int_fast32_t, -1)) << 1) == JAS_CAST(int_fast32_t, -2));203 assert(((JAS_CAST(int_fast32_t, -1)) << 1) == JAS_CAST(int_fast32_t, -2));
196 // The behavior is undefined when x is negative. */204 // The behavior is undefined when x is negative.
197 // We tacitly assume the behavior is equivalent to a signed205 // We tacitly assume the behavior is equivalent to a signed
198 // arithmetic left shift.206 // arithmetic left shift.
199 return x << n;207 return x << n;
@@ -210,11 +218,13 @@ inline static int_fast32_t jas_fast32_asl(int_fast32_t x, unsigned n) · 10 unmodified lines
210/* Compute the product of two size_t integers with overflow checking. */218/* Compute the product of two size_t integers with overflow checking. */
211inline static bool jas_safe_size_mul(size_t x, size_t y, size_t *result)219inline static bool jas_safe_size_mul(size_t x, size_t y, size_t *result)
212{220{
213#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 5)221#if jas_has_builtin(__builtin_mul_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
214 size_t result_buffer;222 size_t result_buffer;
215 if (!result)223 bool valid = !__builtin_mul_overflow(x, y, &result_buffer);
216 result = &result_buffer;224 if (valid && result) {
217 return !__builtin_mul_overflow(x, y, result);225 *result = result_buffer;
226 }
227 return valid;
218#else228#else
219 /* Check if overflow would occur */229 /* Check if overflow would occur */
220 if (x && y > SIZE_MAX / x) {230 if (x && y > SIZE_MAX / x) {
@@ -246,11 +256,13 @@ inline static bool jas_safe_size_mul3(size_t a, size_t b, size_t c, · 25 unmodified lines
246/* Compute the sum of two size_t integers with overflow checking. */256/* Compute the sum of two size_t integers with overflow checking. */
247inline static bool jas_safe_size_add(size_t x, size_t y, size_t *result)257inline static bool jas_safe_size_add(size_t x, size_t y, size_t *result)
248{258{
249#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 5)259#if jas_has_builtin(__builtin_add_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
250 size_t result_buffer;260 size_t result_buffer;
251 if (!result)261 bool valid = !__builtin_add_overflow(x, y, &result_buffer);
252 result = &result_buffer;262 if (valid && result) {
253 return !__builtin_add_overflow(x, y, result);263 *result = result_buffer;
264 }
265 return valid;
254#else266#else
255 if (y > SIZE_MAX - x) {267 if (y > SIZE_MAX - x) {
256 return false;268 return false;
@@ -265,11 +277,13 @@ inline static bool jas_safe_size_add(size_t x, size_t y, size_t *result) · 8 unmodified lines
265/* Compute the difference of two size_t integers with overflow checking. */277/* Compute the difference of two size_t integers with overflow checking. */
266inline static bool jas_safe_size_sub(size_t x, size_t y, size_t *result)278inline static bool jas_safe_size_sub(size_t x, size_t y, size_t *result)
267{279{
268#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 5)280#if jas_has_builtin(__builtin_sub_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
269 size_t result_buffer;281 size_t result_buffer;
270 if (!result)282 bool valid = !__builtin_sub_overflow(x, y, &result_buffer);
271 result = &result_buffer;283 if (valid && result) {
272 return !__builtin_sub_overflow(x, y, result);284 *result = result_buffer;
285 }
286 return valid;
273#else287#else
274 if (y > x) {288 if (y > x) {
275 return false;289 return false;
@@ -285,11 +299,13 @@ inline static bool jas_safe_size_sub(size_t x, size_t y, size_t *result) · 9 unmodified lines
285inline static bool jas_safe_intfast32_mul(int_fast32_t x, int_fast32_t y,299inline static bool jas_safe_intfast32_mul(int_fast32_t x, int_fast32_t y,
286 int_fast32_t *result)300 int_fast32_t *result)
287{301{
288#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 5)302#if jas_has_builtin(__builtin_mul_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
289 int_fast32_t result_buffer;303 int_fast32_t result_buffer;
290 if (!result)304 bool valid = !__builtin_mul_overflow(x, y, &result_buffer);
291 result = &result_buffer;305 if (valid && result) {
292 return !__builtin_mul_overflow(x, y, result);306 *result = result_buffer;
307 }
308 return valid;
293#else309#else
294 if (x > 0) {310 if (x > 0) {
295 /* x is positive */311 /* x is positive */
@@ -344,11 +360,13 @@ inline static bool jas_safe_intfast32_mul3(int_fast32_t a, int_fast32_t b, · 48 unmodified lines
344inline static bool jas_safe_intfast32_add(int_fast32_t x, int_fast32_t y,360inline static bool jas_safe_intfast32_add(int_fast32_t x, int_fast32_t y,
345 int_fast32_t *result)361 int_fast32_t *result)
346{362{
347#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ > 5)363#if jas_has_builtin(__builtin_add_overflow) || (defined(__GNUC__) && __GNUC__ > 5)
348 int_fast32_t result_buffer;364 int_fast32_t result_buffer;
349 if (!result)365 bool valid = !__builtin_add_overflow(x, y, &result_buffer);
350 result = &result_buffer;366 if (valid && result) {
351 return !__builtin_add_overflow(x, y, result);367 *result = result_buffer;
368 }
369 return valid;
352#else370#else
353 if ((y > 0 && x > INT_FAST32_MAX - y) ||371 if ((y > 0 && x > INT_FAST32_MAX - y) ||
354 (y < 0 && x < INT_FAST32_MIN - y)) {372 (y < 0 && x < INT_FAST32_MIN - y)) {
@@ -361,6 +379,357 @@ inline static bool jas_safe_intfast32_add(int_fast32_t x, int_fast32_t y, · 6 unmodified lines
361#endif379#endif
362}380}
363 381
382#if 0
383/*
384This function is potentially useful but not currently used.
385So, it is commented out.
386*/
387inline static bool jas_safe_uint_mul(unsigned x, unsigned y, unsigned *result)
388{
389 /* Check if overflow would occur */
390 if (x && y > UINT_MAX / x) {
391 /* Overflow would occur. */
392 return false;
393 }
394 if (result) {
395 *result = x * y;
396 }
397 return true;
398}
399#endif
400
401/******************************************************************************\
402* Safe 32-bit unsigned integer arithmetic (i.e., with overflow checking).
403\******************************************************************************/
404
405#define JAS_SAFEUI32_MAX (0xffffffffU)
406
407typedef struct {
408 bool valid;
409 uint_least32_t value;
410} jas_safeui32_t;
411
412JAS_ATTRIBUTE_CONST
413static inline jas_safeui32_t jas_safeui32_from_ulong(unsigned long x)
414{
415 jas_safeui32_t result;
416 result.valid = 1;
417 result.value = JAS_CAST(uint_least32_t, x);
418 return result;
419}
420
421JAS_ATTRIBUTE_PURE
422static inline bool jas_safeui32_to_intfast32(jas_safeui32_t x,
423 int_fast32_t* y)
424{
425 if (x.value <= INT_FAST32_MAX) {
426 *y = x.value;
427 return true;
428 } else {
429 return false;
430 }
431}
432
433JAS_ATTRIBUTE_CONST
434static inline jas_safeui32_t jas_safeui32_add(jas_safeui32_t x,
435 jas_safeui32_t y)
436{
437 jas_safeui32_t result;
438 if (x.valid && y.valid && y.value <= UINT_LEAST32_MAX - x.value) {
439 result.valid = true;
440 result.value = x.value + y.value;
441 } else {
442 result.valid = false;
443 result.value = 0;
444 }
445 return result;
446}
447
448JAS_ATTRIBUTE_CONST
449static inline
450jas_safeui32_t jas_safeui32_sub(jas_safeui32_t x, jas_safeui32_t y)
451{
452 jas_safeui32_t result;
453 if (x.valid && y.valid && y.value <= x.value) {
454 result.valid = true;
455 result.value = x.value - y.value;
456 } else {
457 result.valid = false;
458 result.value = 0;
459 }
460 return result;
461}
462
463JAS_ATTRIBUTE_CONST
464static inline jas_safeui32_t jas_safeui32_mul(jas_safeui32_t x,
465 jas_safeui32_t y)
466{
467 jas_safeui32_t result;
468 if (!x.valid || !y.valid || (x.value && y.value > UINT_LEAST32_MAX /
469 x.value)) {
470 result.valid = false;
471 result.value = 0;
472 } else {
473 result.valid = true;
474 result.value = x.value * y.value;
475 }
476 return result;
477}
478
479/******************************************************************************\
480* Safe 64-bit signed integer arithmetic (i.e., with overflow checking).
481\******************************************************************************/
482
483typedef struct {
484 bool valid;
485 int_least64_t value;
486} jas_safei64_t;
487
488JAS_ATTRIBUTE_CONST
489static inline
490jas_safei64_t jas_safei64_from_intmax(intmax_t x)
491{
492 jas_safei64_t result;
493 result.valid = true;
494 result.value = JAS_CAST(int_least64_t, x);
495 return result;
496}
497
498JAS_ATTRIBUTE_CONST
499static inline
500jas_safei64_t jas_safei64_add(jas_safei64_t x, jas_safei64_t y)
501{
502 jas_safei64_t result;
503 if (((y.value > 0) && (x.value > (INT_LEAST64_MAX - y.value))) ||
504 ((y.value < 0) && (x.value < (INT_LEAST64_MIN - y.value)))) {
505 result.value = false;
506 result.value = 0;
507 } else {
508 result.valid = true;
509 result.value = x.value + y.value;
510 }
511 return result;
512}
513
514JAS_ATTRIBUTE_CONST
515static inline
516jas_safei64_t jas_safei64_sub(jas_safei64_t x, jas_safei64_t y)
517{
518 jas_safei64_t result;
519 if ((y.value > 0 && x.value < INT_LEAST64_MIN + y.value) ||
520 (y.value < 0 && x.value > INT_LEAST64_MAX + y.value)) {
521 result.valid = false;
522 result.value = 0;
523 } else {
524 result.valid = true;
525 result.value = x.value - y.value;
526 }
527 return result;
528}
529
530JAS_ATTRIBUTE_CONST
531static inline
532jas_safei64_t jas_safei64_mul(jas_safei64_t x, jas_safei64_t y)
533{
534 jas_safei64_t result;
535 if (x.value > 0) { /* x.value is positive */
536 if (y.value > 0) { /* x.value and y.value are positive */
537 if (x.value > (INT_LEAST64_MAX / y.value)) {
538 goto error;
539 }
540 } else { /* x.value positive, y.value nonpositive */
541 if (y.value < (INT_LEAST64_MIN / x.value)) {
542 goto error;
543 }
544 } /* x.value positive, y.value nonpositive */
545 } else { /* x.value is nonpositive */
546 if (y.value > 0) { /* x.value is nonpositive, y.value is positive */
547 if (x.value < (INT_LEAST64_MIN / y.value)) {
548 goto error;
549 }
550 } else { /* x.value and y.value are nonpositive */
551 if ( (x.value != 0) && (y.value < (INT_LEAST64_MAX / x.value))) {
552 goto error;
553 }
554 } /* End if x.value and y.value are nonpositive */
555 } /* End if x.value is nonpositive */
556 result.valid = true;
557 result.value = x.value * y.value;
558 return result;
559error:
560 result.valid = false;
561 result.value = 0;
562 return result;
563}
564
565#if 0
566JAS_ATTRIBUTE_CONST
567static inline
568jas_safei64_t jas_safei64_div(jas_safei64_t x, jas_safei64_t y)
569{
570 // TODO/FIXME: Not yet implemented.
571 jas_safei64_t result;
572 result.valid = false;
573 result.value = 0;
574 return result;
575}
576#endif
577
578JAS_ATTRIBUTE_CONST
579static inline
580jas_i32_t jas_safei64_to_i32(jas_safei64_t x, jas_i32_t invalid_value)
581{
582 jas_i32_t result;
583 if (x.valid && x.value >= JAS_I32_MIN && x.value <= JAS_I32_MAX) {
584 result = JAS_CAST(jas_i32_t, x.value);
585 } else {
586 result = invalid_value;
587 }
588 return result;
589}
590
591/******************************************************************************\
592* Safe 64-bit unsigned integer arithmetic (i.e., with overflow checking).
593\******************************************************************************/
594
595typedef struct {
596 bool valid;
597 uint_least64_t value;
598} jas_safeui64_t;
599
600JAS_ATTRIBUTE_CONST
601static inline
602jas_safeui64_t jas_safeui64_from_intmax(intmax_t x)
603{
604 jas_safeui64_t result;
605 if (x >= 0) {
606 result.valid = true;
607 result.value = JAS_CAST(uint_least64_t, x);
608 } else {
609 result.valid = false;
610 result.value = 0;
611 }
612 return result;
613}
614
615JAS_ATTRIBUTE_CONST
616static inline
617jas_safeui64_t jas_safeui64_add(jas_safeui64_t x, jas_safeui64_t y)
618{
619 jas_safeui64_t result;
620 if (x.valid && y.valid && y.value <= UINT_LEAST64_MAX - x.value) {
621 result.valid = true;
622 result.value = x.value + y.value;
623 } else {
624 result.valid = false;
625 result.value = 0;
626 }
627 return result;
628}
629
630JAS_ATTRIBUTE_CONST
631static inline
632jas_safeui64_t jas_safeui64_sub(jas_safeui64_t x, jas_safeui64_t y)
633{
634 jas_safeui64_t result;
635 if (x.valid && y.valid && y.value <= x.value) {
636 result.valid = true;
637 result.value = x.value - y.value;
638 } else {
639 result.valid = false;
640 result.value = 0;
641 }
642 return result;
643}
644
645JAS_ATTRIBUTE_CONST
646static inline
647jas_safeui64_t jas_safeui64_mul(jas_safeui64_t x, jas_safeui64_t y)
648{
649 jas_safeui64_t result;
650 if (!x.valid || !y.valid || (x.value && y.value > UINT_LEAST64_MAX /
651 x.value)) {
652 result.valid = false;
653 result.value = 0;
654 } else {
655 result.valid = true;
656 result.value = x.value * y.value;
657 }
658 return result;
659}
660
661JAS_ATTRIBUTE_CONST
662static inline
663jas_safeui64_t jas_safeui64_div(jas_safeui64_t x, jas_safeui64_t y)
664{
665 jas_safeui64_t result;
666 if (x.valid && y.valid && y.value) {
667 result.valid = true;
668 result.value = x.value / y.value;
669 } else {
670 result.valid = false;
671 result.value = 0;
672 }
673 return result;
674}
675
676JAS_ATTRIBUTE_CONST
677static inline
678jas_safeui64_t jas_safeui64_pow2_intmax(intmax_t x)
679{
680 jas_safeui64_t result;
681 if (x >= 0 && x < 64) {
682 result.valid = true;
683 result.value = JAS_CAST(uint_least64_t, 1) << x;
684 } else {
685 result.valid = false;
686 result.value = 0;
687 }
688 return result;
689}
690
691JAS_ATTRIBUTE_CONST
692static inline
693int jas_safeui64_to_int(jas_safeui64_t x, int invalid_value)
694{
695 int result;
696 if (x.valid && x.value <= INT_MAX) {
697 result = JAS_CAST(int, x.value);
698 } else {
699 result = invalid_value;
700 }
701 return result;
702}
703
704JAS_ATTRIBUTE_CONST
705static inline
706jas_ui32_t jas_safeui64_to_ui32(jas_safeui64_t x, jas_ui32_t invalid_value)
707{
708 jas_ui32_t result;
709 if (x.valid && x.value <= JAS_UI32_MAX) {
710 result = JAS_CAST(jas_ui32_t, x.value);
711 } else {
712 result = invalid_value;
713 }
714 return result;
715}
716
717JAS_ATTRIBUTE_CONST
718static inline
719jas_i32_t jas_safeui64_to_i32(jas_safeui64_t x, jas_i32_t invalid_value)
720{
721 jas_i32_t result;
722 if (x.valid && x.value <= JAS_I32_MAX) {
723 result = JAS_CAST(jas_i32_t, x.value);
724 } else {
725 result = invalid_value;
726 }
727 return result;
728}
729
730/******************************************************************************\
731\******************************************************************************/
732
364#ifdef __cplusplus733#ifdef __cplusplus
365}734}
366#endif735#endif
jasper/jas_seq.h+271−56
@@ -77,12 +77,18 @@ · 76 unmodified lines
77#include <jasper/jas_config.h> /* IWYU pragma: keep */77#include <jasper/jas_config.h> /* IWYU pragma: keep */
78 78
79#include <jasper/jas_types.h>79#include <jasper/jas_types.h>
80#include <jasper/jas_fix.h>
80#include <jasper/jas_math.h>81#include <jasper/jas_math.h>
81 82
82#ifdef __cplusplus83#ifdef __cplusplus
83extern "C" {84extern "C" {
84#endif85#endif
85 86
87/*!
88 * @addtogroup module_seq
89 * @{
90 */
91
86/******************************************************************************\92/******************************************************************************\
87* Constants.93* Constants.
88\******************************************************************************/94\******************************************************************************/
@@ -95,29 +101,17 @@ extern "C" { · 6 unmodified lines
95\******************************************************************************/101\******************************************************************************/
96 102
97/* An element in a sequence. */103/* An element in a sequence. */
98#ifdef JAS_ENABLE_32BIT104typedef jas_fix_t jas_seqent_t;
99typedef int_least32_t jas_seqent_t;105#define PRIjas_seqent PRIjas_fix
100#define PRIjas_seqent PRIiLEAST32
101#else
102typedef int_fast32_t jas_seqent_t;
103#define PRIjas_seqent PRIiFAST32
104#endif
105 106
106/* An element in a matrix. */107/* An element in a matrix. */
107#ifdef JAS_ENABLE_32BIT108typedef jas_fix_t jas_matent_t;
108typedef int_least32_t jas_matent_t;
109#else
110typedef int_fast32_t jas_matent_t;
111#endif
112 109
113#ifdef JAS_ENABLE_32BIT110typedef jas_fix_t jas_matind_t;
114typedef int_least32_t jas_matind_t;
115#else
116typedef int_fast32_t jas_matind_t;
117#endif
118
119/* Matrix. */
120 111
112/*!
113@brief Matrix type.
114*/
121typedef struct {115typedef struct {
122 116
123 /* Additional state information. */117 /* Additional state information. */
@@ -155,53 +149,86 @@ typedef struct { · 31 unmodified lines
155 149
156} jas_matrix_t;150} jas_matrix_t;
157 151
152/*!
153@struct jas_seq2d_t
154@brief Two-dimensional sequence type.
155*/
158typedef jas_matrix_t jas_seq2d_t;156typedef jas_matrix_t jas_seq2d_t;
157
158/*!
159@struct jas_seq_t
160@brief One-dimensional sequence type.
161*/
159typedef jas_matrix_t jas_seq_t;162typedef jas_matrix_t jas_seq_t;
160 163
161/******************************************************************************\164/******************************************************************************\
162* Functions/macros for matrix class.165* Functions/macros for matrix class.
163\******************************************************************************/166\******************************************************************************/
164 167
165/* Get the number of rows. */168/*!
169@brief
170Get the number of rows in a matrix.
171*/
166JAS_ATTRIBUTE_PURE172JAS_ATTRIBUTE_PURE
167static inline jas_matind_t jas_matrix_numrows(const jas_matrix_t *matrix)173static inline jas_matind_t jas_matrix_numrows(const jas_matrix_t *matrix)
168{174{
169 return matrix->numrows_;175 return matrix->numrows_;
170}176}
171 177
172/* Get the number of columns. */178/*!
179@brief Get the number of columns in a matrix.
180*/
173JAS_ATTRIBUTE_PURE181JAS_ATTRIBUTE_PURE
174static inline jas_matind_t jas_matrix_numcols(const jas_matrix_t *matrix)182static inline jas_matind_t jas_matrix_numcols(const jas_matrix_t *matrix)
175{183{
176 return matrix->numcols_;184 return matrix->numcols_;
177}185}
178 186
187/*!
188@brief
189Get the number of elements in a matrix.
190*/
179JAS_ATTRIBUTE_PURE191JAS_ATTRIBUTE_PURE
180static inline jas_matind_t jas_matrix_size(const jas_matrix_t *matrix)192static inline jas_matind_t jas_matrix_size(const jas_matrix_t *matrix)
181{193{
182 return jas_matrix_numcols(matrix) * jas_matrix_numrows(matrix);194 return jas_matrix_numcols(matrix) * jas_matrix_numrows(matrix);
183}195}
184 196
197/*!
198@brief
199Test if a matrix is empty (i.e., contains no elements).
200*/
185JAS_ATTRIBUTE_PURE201JAS_ATTRIBUTE_PURE
186static inline bool jas_matrix_empty(const jas_matrix_t *matrix)202static inline bool jas_matrix_empty(const jas_matrix_t *matrix)
187{203{
188 return jas_matrix_numcols(matrix) == 0 || jas_matrix_numrows(matrix) == 0;204 return jas_matrix_numcols(matrix) == 0 || jas_matrix_numrows(matrix) == 0;
189}205}
190 206
191/* Get a matrix element. */207/*!
208@brief
209Get a matrix element.
210*/
192JAS_ATTRIBUTE_PURE211JAS_ATTRIBUTE_PURE
193static inline jas_seqent_t jas_matrix_get(const jas_matrix_t *matrix, jas_matind_t i, jas_matind_t j)212static inline jas_seqent_t jas_matrix_get(const jas_matrix_t *matrix, jas_matind_t i, jas_matind_t j)
194{213{
214 assert(i >= 0 && i < matrix->numrows_ && j >= 0 && j < matrix->numcols_);
195 return matrix->rows_[i][j];215 return matrix->rows_[i][j];
196}216}
197 217
198/* Set a matrix element. */218/*!
219@brief
220Set a matrix element.
221*/
199static inline void jas_matrix_set(jas_matrix_t *matrix, jas_matind_t i, jas_matind_t j, jas_seqent_t v)222static inline void jas_matrix_set(jas_matrix_t *matrix, jas_matind_t i, jas_matind_t j, jas_seqent_t v)
200{223{
224 assert(i >= 0 && i < matrix->numrows_ && j >= 0 && j < matrix->numcols_);
201 matrix->rows_[i][j] = v;225 matrix->rows_[i][j] = v;
202}226}
203 227
204/* Get an element from a matrix that is known to be a row or column vector. */228/*!
229@brief
230Get an element from a matrix that is known to be a row or column vector.
231*/
205JAS_ATTRIBUTE_PURE232JAS_ATTRIBUTE_PURE
206static inline jas_seqent_t jas_matrix_getv(const jas_matrix_t *matrix, jas_matind_t i)233static inline jas_seqent_t jas_matrix_getv(const jas_matrix_t *matrix, jas_matind_t i)
207{234{
@@ -210,7 +237,10 @@ static inline jas_seqent_t jas_matrix_getv(const jas_matrix_t *matrix, jas_matin · 2 unmodified lines
210 : matrix->rows_[i][0];237 : matrix->rows_[i][0];
211}238}
212 239
213/* Set an element in a matrix that is known to be a row or column vector. */240/*!
241@brief
242Set an element in a matrix that is known to be a row or column vector.
243*/
214static inline void jas_matrix_setv(jas_matrix_t *matrix, jas_matind_t i, jas_seqent_t v)244static inline void jas_matrix_setv(jas_matrix_t *matrix, jas_matind_t i, jas_seqent_t v)
215{245{
216 if (matrix->numrows_ == 1)246 if (matrix->numrows_ == 1)
@@ -219,13 +249,20 @@ static inline void jas_matrix_setv(jas_matrix_t *matrix, jas_matind_t i, jas_seq · 2 unmodified lines
219 matrix->rows_[i][0] = v;249 matrix->rows_[i][0] = v;
220}250}
221 251
222/* Get the address of an element in a matrix. */252/*!
253@brief
254Get the address of an element in a matrix.
255*/
223JAS_ATTRIBUTE_PURE256JAS_ATTRIBUTE_PURE
224static inline jas_seqent_t *jas_matrix_getref(const jas_matrix_t *matrix, jas_matind_t i, jas_matind_t j)257static inline jas_seqent_t *jas_matrix_getref(const jas_matrix_t *matrix, jas_matind_t i, jas_matind_t j)
225{258{
226 return &matrix->rows_[i][j];259 return &matrix->rows_[i][j];
227}260}
228 261
262/*!
263@brief
264Get a reference to a particular row of a 2-D sequence.
265*/
229JAS_ATTRIBUTE_PURE266JAS_ATTRIBUTE_PURE
230static inline jas_seqent_t *jas_matrix_getvref(const jas_matrix_t *matrix, jas_matind_t i)267static inline jas_seqent_t *jas_matrix_getvref(const jas_matrix_t *matrix, jas_matind_t i)
231{268{
@@ -234,50 +271,100 @@ static inline jas_seqent_t *jas_matrix_getvref(const jas_matrix_t *matrix, jas_m · 2 unmodified lines
234 : jas_matrix_getref(matrix, 0, i);271 : jas_matrix_getref(matrix, 0, i);
235}272}
236 273
237/* Create a matrix with the specified dimensions. */274/*!
238JAS_DLLEXPORT jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols);275@brief
276Create a matrix with the specified dimensions.
277*/
278JAS_EXPORT
279jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols);
239 280
240/* Destroy a matrix. */281/*!
241JAS_DLLEXPORT void jas_matrix_destroy(jas_matrix_t *matrix);282@brief
283Destroy a matrix.
284*/
285JAS_EXPORT
286void jas_matrix_destroy(jas_matrix_t *matrix);
242 287
243/* Resize a matrix. The previous contents of the matrix are lost. */288/*!
244JAS_DLLEXPORT int jas_matrix_resize(jas_matrix_t *matrix, jas_matind_t numrows, jas_matind_t numcols);289@brief
290Resize a matrix. The previous contents of the matrix are lost.
291*/
292JAS_EXPORT
293int jas_matrix_resize(jas_matrix_t *matrix, jas_matind_t numrows, jas_matind_t numcols);
245 294
246JAS_DLLEXPORT int jas_matrix_output(jas_matrix_t *matrix, int fd);295/*!
296@brief
297Write a matrix to a C standard library stream.
298*/
299JAS_EXPORT
300int jas_matrix_output(jas_matrix_t *matrix, FILE *out);
247 301
248/* Create a matrix that references part of another matrix. */302/*!
249JAS_DLLEXPORT int jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, jas_matind_t r0,303@brief
304Create a matrix that references part of another matrix.
305*/
306JAS_EXPORT
307int jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, jas_matind_t r0,
250 jas_matind_t c0, jas_matind_t r1, jas_matind_t c1);308 jas_matind_t c0, jas_matind_t r1, jas_matind_t c1);
251 309
252/* Create a matrix that is a reference to a row of another matrix. */310/*!
311@brief
312Create a matrix that is a reference to a row of another matrix.
313*/
253static inline int jas_matrix_bindrow(jas_matrix_t *mat0, jas_matrix_t *mat1, jas_matind_t r)314static inline int jas_matrix_bindrow(jas_matrix_t *mat0, jas_matrix_t *mat1, jas_matind_t r)
254{315{
255 return jas_matrix_bindsub(mat0, mat1, r, 0, r, mat1->numcols_ - 1);316 return jas_matrix_bindsub(mat0, mat1, r, 0, r, mat1->numcols_ - 1);
256}317}
257 318
258/* Create a matrix that is a reference to a column of another matrix. */319/*!
320@brief
321Create a matrix that is a reference to a column of another matrix.
322*/
259static inline int jas_matrix_bindcol(jas_matrix_t *mat0, jas_matrix_t *mat1, jas_matind_t c)323static inline int jas_matrix_bindcol(jas_matrix_t *mat0, jas_matrix_t *mat1, jas_matind_t c)
260{324{
261 return jas_matrix_bindsub(mat0, mat1, 0, c, mat1->numrows_ - 1, c);325 return jas_matrix_bindsub(mat0, mat1, 0, c, mat1->numrows_ - 1, c);
262}326}
263 327
264/* Clip the values of matrix elements to the specified range. */328/*!
265JAS_DLLEXPORT void jas_matrix_clip(jas_matrix_t *matrix, jas_seqent_t minval,329@brief
330Clip the values of matrix elements to the specified range.
331*/
332JAS_EXPORT
333void jas_matrix_clip(jas_matrix_t *matrix, jas_seqent_t minval,
266 jas_seqent_t maxval);334 jas_seqent_t maxval);
267 335
268/* Arithmetic shift left of all elements in a matrix. */336/*!
269JAS_DLLEXPORT void jas_matrix_asl(jas_matrix_t *matrix, unsigned n);337@brief
338Arithmetic shift left of all elements in a matrix.
339*/
340JAS_EXPORT
341void jas_matrix_asl(jas_matrix_t *matrix, unsigned n);
270 342
271/* Arithmetic shift right of all elements in a matrix. */343/*!
272JAS_DLLEXPORT void jas_matrix_asr(jas_matrix_t *matrix, unsigned n);344@brief
345Arithmetic shift right of all elements in a matrix.
346*/
347JAS_EXPORT
348void jas_matrix_asr(jas_matrix_t *matrix, unsigned n);
273 349
274/* Almost-but-not-quite arithmetic shift right of all elements in a matrix. */350/*!
275JAS_DLLEXPORT void jas_matrix_divpow2(jas_matrix_t *matrix, unsigned n);351@brief
352Almost-but-not-quite arithmetic shift right of all elements in a matrix.
353*/
354JAS_EXPORT
355void jas_matrix_divpow2(jas_matrix_t *matrix, unsigned n);
276 356
277/* Set all elements of a matrix to the specified value. */357/*!
278JAS_DLLEXPORT void jas_matrix_setall(jas_matrix_t *matrix, jas_seqent_t val);358@brief
359Set all elements of a matrix to the specified value.
360*/
361JAS_EXPORT
362void jas_matrix_setall(jas_matrix_t *matrix, jas_seqent_t val);
279 363
280/* The spacing between rows of a matrix. */364/*!
365@brief
366The spacing between rows of a matrix.
367*/
281JAS_ATTRIBUTE_PURE368JAS_ATTRIBUTE_PURE
282static inline size_t jas_matrix_rowstep(const jas_matrix_t *matrix)369static inline size_t jas_matrix_rowstep(const jas_matrix_t *matrix)
283{370{
@@ -286,7 +373,10 @@ static inline size_t jas_matrix_rowstep(const jas_matrix_t *matrix) · 2 unmodified lines
286 : 0u;373 : 0u;
287}374}
288 375
289/* The spacing between columns of a matrix. */376/*!
377@brief
378The spacing between columns of a matrix.
379*/
290JAS_ATTRIBUTE_PURE380JAS_ATTRIBUTE_PURE
291static inline size_t jas_matrix_step(const jas_matrix_t *matrix)381static inline size_t jas_matrix_step(const jas_matrix_t *matrix)
292{382{
@@ -295,101 +385,181 @@ static inline size_t jas_matrix_step(const jas_matrix_t *matrix) · 2 unmodified lines
295 : 1;385 : 1;
296}386}
297 387
298/* Compare two matrices for equality. */388/*!
299JAS_DLLEXPORT int jas_matrix_cmp(jas_matrix_t *mat0, jas_matrix_t *mat1);389@brief
390Compare two matrices for equality.
391*/
392JAS_EXPORT
393int jas_matrix_cmp(jas_matrix_t *mat0, jas_matrix_t *mat1);
300 394
301JAS_DLLEXPORT jas_matrix_t *jas_matrix_copy(jas_matrix_t *x);395/*!
396@brief
397Copy a matrix.
398*/
399JAS_EXPORT
400jas_matrix_t *jas_matrix_copy(jas_matrix_t *x);
302 401
303JAS_DLLEXPORT jas_matrix_t *jas_matrix_input(int);402/*!
403@brief
404Read a matrix from a C standard library stream.
405*/
406JAS_EXPORT
407jas_matrix_t *jas_matrix_input(FILE *);
304 408
409/*!
410@brief
411*/
305JAS_ATTRIBUTE_CONST412JAS_ATTRIBUTE_CONST
306static inline jas_seqent_t jas_seqent_asl(jas_seqent_t x, unsigned n)413static inline jas_seqent_t jas_seqent_asl(jas_seqent_t x, unsigned n)
307{414{
415#if 0
308#ifdef JAS_ENABLE_32BIT416#ifdef JAS_ENABLE_32BIT
309 return jas_least32_asl(x, n);417 return jas_least32_asl(x, n);
310#else418#else
311 return jas_fast32_asl(x, n);419 return jas_fast32_asl(x, n);
312#endif420#endif
421#endif
422 return jas_fix_asl(x, n);
313}423}
314 424
425/*!
426@brief
427*/
315JAS_ATTRIBUTE_CONST428JAS_ATTRIBUTE_CONST
316static inline jas_seqent_t jas_seqent_asr(jas_seqent_t x, unsigned n)429static inline jas_seqent_t jas_seqent_asr(jas_seqent_t x, unsigned n)
317{430{
431#if 0
318#ifdef JAS_ENABLE_32BIT432#ifdef JAS_ENABLE_32BIT
319 return jas_least32_asr(x, n);433 return jas_least32_asr(x, n);
320#else434#else
321 return jas_fast32_asr(x, n);435 return jas_fast32_asr(x, n);
322#endif436#endif
437#endif
438 return jas_fix_asr(x, n);
323}439}
324 440
325/******************************************************************************\441/******************************************************************************\
326* Functions/macros for 2-D sequence class.442* Functions/macros for 2-D sequence class.
327\******************************************************************************/443\******************************************************************************/
328 444
329JAS_DLLEXPORT jas_seq2d_t *jas_seq2d_copy(jas_seq2d_t *x);445/*!
446@brief
447Copy a 2-D sequence.
448*/
449JAS_EXPORT
450jas_seq2d_t *jas_seq2d_copy(jas_seq2d_t *x);
330 451
331JAS_DLLEXPORT jas_matrix_t *jas_seq2d_create(jas_matind_t xstart, jas_matind_t ystart,452/*!
453@brief
454Create a 2-D sequence.
455*/
456JAS_EXPORT
457jas_matrix_t *jas_seq2d_create(jas_matind_t xstart, jas_matind_t ystart,
332 jas_matind_t xend, jas_matind_t yend);458 jas_matind_t xend, jas_matind_t yend);
333 459
460/*!
461@brief
462Destroy a 2-D sequence.
463*/
334static inline void jas_seq2d_destroy(jas_seq2d_t *s)464static inline void jas_seq2d_destroy(jas_seq2d_t *s)
335{465{
336 jas_matrix_destroy(s);466 jas_matrix_destroy(s);
337}467}
338 468
469/*!
470@brief
471Get the starting x-coordinate of the sequence.
472*/
339JAS_ATTRIBUTE_PURE473JAS_ATTRIBUTE_PURE
340static inline jas_matind_t jas_seq2d_xstart(const jas_seq2d_t *s)474static inline jas_matind_t jas_seq2d_xstart(const jas_seq2d_t *s)
341{475{
342 return s->xstart_;476 return s->xstart_;
343}477}
344 478
479/*!
480@brief
481Get the starting y-coordinate of the sequence.
482*/
345JAS_ATTRIBUTE_PURE483JAS_ATTRIBUTE_PURE
346static inline jas_matind_t jas_seq2d_ystart(const jas_seq2d_t *s)484static inline jas_matind_t jas_seq2d_ystart(const jas_seq2d_t *s)
347{485{
348 return s->ystart_;486 return s->ystart_;
349}487}
350 488
489/*!
490@brief
491Get the ending x-coordinate of the sequence.
492*/
351JAS_ATTRIBUTE_PURE493JAS_ATTRIBUTE_PURE
352static inline jas_matind_t jas_seq2d_xend(const jas_seq2d_t *s)494static inline jas_matind_t jas_seq2d_xend(const jas_seq2d_t *s)
353{495{
354 return s->xend_;496 return s->xend_;
355}497}
356 498
499/*!
500@brief
501Get the ending y-coordinate of the sequence.
502*/
357JAS_ATTRIBUTE_PURE503JAS_ATTRIBUTE_PURE
358static inline jas_matind_t jas_seq2d_yend(const jas_seq2d_t *s)504static inline jas_matind_t jas_seq2d_yend(const jas_seq2d_t *s)
359{505{
360 return s->yend_;506 return s->yend_;
361}507}
362 508
509/*!
510@brief
511Get a pointer (i.e., reference) to an element of a 2-D sequence.
512*/
363JAS_ATTRIBUTE_PURE513JAS_ATTRIBUTE_PURE
364static inline jas_seqent_t *jas_seq2d_getref(const jas_seq2d_t *s, jas_matind_t x, jas_matind_t y)514static inline jas_seqent_t *jas_seq2d_getref(const jas_seq2d_t *s, jas_matind_t x, jas_matind_t y)
365{515{
366 return jas_matrix_getref(s, y - s->ystart_, x - s->xstart_);516 return jas_matrix_getref(s, y - s->ystart_, x - s->xstart_);
367}517}
368 518
519/*!
520@brief
521Get an element of a 2-D sequence.
522*/
369JAS_ATTRIBUTE_PURE523JAS_ATTRIBUTE_PURE
370static inline jas_seqent_t jas_seq2d_get(const jas_seq2d_t *s, jas_matind_t x, jas_matind_t y)524static inline jas_seqent_t jas_seq2d_get(const jas_seq2d_t *s, jas_matind_t x, jas_matind_t y)
371{525{
372 return jas_matrix_get(s, y - s->ystart_, x - s->xstart_);526 return jas_matrix_get(s, y - s->ystart_, x - s->xstart_);
373}527}
374 528
529/*!
530@brief
531Get the stride between successive rows in the sequence.
532*/
375JAS_ATTRIBUTE_PURE533JAS_ATTRIBUTE_PURE
376static inline size_t jas_seq2d_rowstep(const jas_seq2d_t *s)534static inline size_t jas_seq2d_rowstep(const jas_seq2d_t *s)
377{535{
378 return jas_matrix_rowstep(s);536 return jas_matrix_rowstep(s);
379}537}
380 538
539/*!
540@brief
541Get the number of columns in the sequence.
542*/
381JAS_ATTRIBUTE_PURE543JAS_ATTRIBUTE_PURE
382static inline unsigned jas_seq2d_width(const jas_seq2d_t *s)544static inline unsigned jas_seq2d_width(const jas_seq2d_t *s)
383{545{
384 return (unsigned)(s->xend_ - s->xstart_);546 return (unsigned)(s->xend_ - s->xstart_);
385}547}
386 548
549/*!
550@brief
551Get the number of rows in the sequence.
552*/
387JAS_ATTRIBUTE_PURE553JAS_ATTRIBUTE_PURE
388static inline unsigned jas_seq2d_height(const jas_seq2d_t *s)554static inline unsigned jas_seq2d_height(const jas_seq2d_t *s)
389{555{
390 return (unsigned)(s->yend_ - s->ystart_);556 return (unsigned)(s->yend_ - s->ystart_);
391}557}
392 558
559/*!
560@brief
561Set the shift (i.e., starting x- and y-coordinates) of the sequence.
562*/
393static inline void jas_seq2d_setshift(jas_seq2d_t *s, jas_matind_t x, jas_matind_t y)563static inline void jas_seq2d_setshift(jas_seq2d_t *s, jas_matind_t x, jas_matind_t y)
394{564{
395 s->xstart_ = x;565 s->xstart_ = x;
@@ -398,64 +568,109 @@ static inline void jas_seq2d_setshift(jas_seq2d_t *s, jas_matind_t x, jas_matind · 2 unmodified lines
398 s->yend_ = s->ystart_ + s->numrows_;568 s->yend_ = s->ystart_ + s->numrows_;
399}569}
400 570
571/*!
572@brief
573Get the number of elements in the sequence.
574*/
401JAS_ATTRIBUTE_PURE575JAS_ATTRIBUTE_PURE
402static inline jas_matind_t jas_seq2d_size(const jas_seq2d_t *s)576static inline jas_matind_t jas_seq2d_size(const jas_seq2d_t *s)
403{577{
404 return jas_seq2d_width(s) * jas_seq2d_height(s);578 return jas_seq2d_width(s) * jas_seq2d_height(s);
405}579}
406 580
581/*!
582@brief
583Test if the sequence is empty (i.e., contains no elements).
584*/
407JAS_ATTRIBUTE_PURE585JAS_ATTRIBUTE_PURE
408static inline bool jas_seq2d_empty(const jas_seq2d_t *s)586static inline bool jas_seq2d_empty(const jas_seq2d_t *s)
409{587{
410 return jas_seq2d_width(s) == 0 || jas_seq2d_height(s) == 0;588 return jas_seq2d_width(s) == 0 || jas_seq2d_height(s) == 0;
411}589}
412 590
413JAS_DLLEXPORT int jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, jas_matind_t xstart,591/*!
592@brief
593Initialize a sequence to reference a subsequence of another sequence.
594*/
595JAS_EXPORT
596int jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, jas_matind_t xstart,
414 jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend);597 jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend);
415 598
416/******************************************************************************\599/******************************************************************************\
417* Functions/macros for 1-D sequence class.600* Functions/macros for 1-D sequence class.
418\******************************************************************************/601\******************************************************************************/
419 602
603/*!
604@brief
605Create a 1-D sequence.
606*/
420static inline jas_seq_t *jas_seq_create(jas_matind_t start, jas_matind_t end)607static inline jas_seq_t *jas_seq_create(jas_matind_t start, jas_matind_t end)
421{608{
422 return jas_seq2d_create(start, 0, end, 1);609 return jas_seq2d_create(start, 0, end, 1);
423}610}
424 611
612/*!
613@brief
614Destroy a 1-D sequence.
615*/
425static inline void jas_seq_destroy(jas_seq_t *seq)616static inline void jas_seq_destroy(jas_seq_t *seq)
426{617{
427 jas_seq2d_destroy(seq);618 jas_seq2d_destroy(seq);
428}619}
429 620
621/*!
622@brief
623Set an element of a sequence.
624*/
430static inline void jas_seq_set(jas_seq_t *seq, jas_matind_t i, jas_seqent_t v)625static inline void jas_seq_set(jas_seq_t *seq, jas_matind_t i, jas_seqent_t v)
431{626{
432 seq->rows_[0][i - seq->xstart_] = v;627 seq->rows_[0][i - seq->xstart_] = v;
433}628}
434 629
630/*!
631@brief
632Get a pointer (i.e., reference) to an element of a sequence.
633*/
435JAS_ATTRIBUTE_PURE634JAS_ATTRIBUTE_PURE
436static inline jas_seqent_t *jas_seq_getref(const jas_seq_t *seq, jas_matind_t i)635static inline jas_seqent_t *jas_seq_getref(const jas_seq_t *seq, jas_matind_t i)
437{636{
438 return &seq->rows_[0][i - seq->xstart_];637 return &seq->rows_[0][i - seq->xstart_];
439}638}
440 639
640/*!
641@brief
642Get an element of a sequence.
643*/
441JAS_ATTRIBUTE_PURE644JAS_ATTRIBUTE_PURE
442static inline jas_seqent_t jas_seq_get(const jas_seq_t *seq, jas_matind_t i)645static inline jas_seqent_t jas_seq_get(const jas_seq_t *seq, jas_matind_t i)
443{646{
444 return seq->rows_[0][i - seq->xstart_];647 return seq->rows_[0][i - seq->xstart_];
445}648}
446 649
650/*!
651@brief
652Get the starting index of a sequence.
653*/
447JAS_ATTRIBUTE_PURE654JAS_ATTRIBUTE_PURE
448static inline jas_matind_t jas_seq_start(const jas_seq_t *seq)655static inline jas_matind_t jas_seq_start(const jas_seq_t *seq)
449{656{
450 return seq->xstart_;657 return seq->xstart_;
451}658}
452 659
660/*!
661@brief
662Get the ending index of a sequence.
663*/
453JAS_ATTRIBUTE_PURE664JAS_ATTRIBUTE_PURE
454static inline jas_matind_t jas_seq_end(const jas_seq_t *seq)665static inline jas_matind_t jas_seq_end(const jas_seq_t *seq)
455{666{
456 return seq->xend_;667 return seq->xend_;
457}668}
458 669
670/*!
671 * @}
672 */
673
459#ifdef __cplusplus674#ifdef __cplusplus
460}675}
461#endif676#endif
jasper/jas_stream.h+201−77
@@ -75,6 +75,10 @@ · 74 unmodified lines
75 75
76/* The configuration header file should be included first. */76/* The configuration header file should be included first. */
77#include <jasper/jas_config.h> /* IWYU pragma: export */77#include <jasper/jas_config.h> /* IWYU pragma: export */
78
79#if defined(JAS_HAVE_FCNTL_H)
80#include <fcntl.h>
81#endif
78#include <jasper/jas_types.h>82#include <jasper/jas_types.h>
79 83
80#ifdef __cplusplus84#ifdef __cplusplus
@@ -82,7 +86,7 @@ extern "C" { · 1 unmodified line
82#endif86#endif
83 87
84/*!88/*!
85 * @addtogroup iostreams89 * @addtogroup module_iostreams
86 * @{90 * @{
87 */91 */
88 92
@@ -95,8 +99,6 @@ extern "C" { · 6 unmodified lines
95#define O_BINARY 099#define O_BINARY 0
96#endif100#endif
97 101
98#define EOF (-1)
99
100/*102/*
101 * Stream open flags.103 * Stream open flags.
102 */104 */
@@ -176,10 +178,10 @@ typedef void jas_stream_obj_t; · 73 unmodified lines
176typedef struct {178typedef struct {
177 179
178 /* Read characters from a file object. */180 /* Read characters from a file object. */
179 int (*read_)(jas_stream_obj_t *obj, char *buf, unsigned cnt);181 ssize_t (*read_)(jas_stream_obj_t *obj, char *buf, size_t cnt);
180 182
181 /* Write characters to a file object. */183 /* Write characters to a file object. */
182 int (*write_)(jas_stream_obj_t *obj, const char *buf, unsigned cnt);184 ssize_t (*write_)(jas_stream_obj_t *obj, const char *buf, size_t cnt);
183 185
184 /* Set the position for a file object. */186 /* Set the position for a file object. */
185 long (*seek_)(jas_stream_obj_t *obj, long offset, int origin);187 long (*seek_)(jas_stream_obj_t *obj, long offset, int origin);
@@ -189,8 +191,15 @@ typedef struct { · 3 unmodified lines
189 191
190} jas_stream_ops_t;192} jas_stream_ops_t;
191 193
192/*194/*!
193 * Stream object.195@brief
196I/O stream object.
197
198@warning
199Library users should never directly access any of the members of this
200class.
201The functions/macros provided by the JasPer library API should always
202be used.
194 */203 */
195 204
196typedef struct {205typedef struct {
@@ -248,6 +257,7 @@ typedef struct { · 51 unmodified lines
248typedef struct {257typedef struct {
249 int fd;258 int fd;
250 int flags;259 int flags;
260 char pathname[L_tmpnam + 1];
251} jas_stream_fileobj_t;261} jas_stream_fileobj_t;
252 262
253/* Delete underlying file object upon stream close. */263/* Delete underlying file object upon stream close. */
@@ -268,10 +278,10 @@ typedef struct { · 14 unmodified lines
268 size_t bufsize_;278 size_t bufsize_;
269 279
270 /* The length of the file. */280 /* The length of the file. */
271 uint_fast32_t len_;281 size_t len_;
272 282
273 /* The seek position. */283 /* The seek position. */
274 uint_fast32_t pos_;284 size_t pos_;
275 285
276 /* Is the buffer growable? */286 /* Is the buffer growable? */
277 int growable_;287 int growable_;
@@ -299,7 +309,7 @@ C standard library. · 21 unmodified lines
299Upon success, a pointer to the opened stream is returned.309Upon success, a pointer to the opened stream is returned.
300Otherwise, a null pointer is returned.310Otherwise, a null pointer is returned.
301*/311*/
302JAS_DLLEXPORT312JAS_EXPORT
303jas_stream_t *jas_stream_fopen(const char *filename, const char *mode);313jas_stream_t *jas_stream_fopen(const char *filename, const char *mode);
304 314
305/*!315/*!
@@ -325,26 +335,20 @@ If buffer is not 0: · 19 unmodified lines
325buffer_size (which, in this case, is not currently allowed to be zero) is335buffer_size (which, in this case, is not currently allowed to be zero) is
326the size of the (nongrowable) buffer pointed to by buffer.336the size of the (nongrowable) buffer pointed to by buffer.
327</ul>337</ul>
328
329@warning
330TODO/FIXME: The type of the buffer_size parameter will be
331changed to size_t in the future.
332
333@warning
334TODO/FIXME:
335In a later release, this function will be changed to have the same
336prototype as jas_stream_memopen2, at which point jas_stream_memopen2
337will be removed.
338*/338*/
339JAS_DLLEXPORT339JAS_EXPORT
340jas_stream_t *jas_stream_memopen(char *buffer, int buffer_size);340jas_stream_t *jas_stream_memopen(char *buffer, size_t buffer_size);
341 341
342/*!342/*!
343@warning343@brief
344This function will be renamed jas_stream_memopen in a future release.344Do not use.
345@deprecated
345Do not use this function.346Do not use this function.
347This function is deprecated.
348Use jas_stream_memopen instead.
346*/349*/
347JAS_DLLEXPORT350JAS_DEPRECATED
351JAS_EXPORT
348jas_stream_t *jas_stream_memopen2(char *buffer, size_t buffer_size);352jas_stream_t *jas_stream_memopen2(char *buffer, size_t buffer_size);
349 353
350/*!354/*!
@@ -361,9 +365,51 @@ in the C standard library. · 10 unmodified lines
361Upon success, a pointer to the opened stream is returned.365Upon success, a pointer to the opened stream is returned.
362Otherwise, a null pointer is returned.366Otherwise, a null pointer is returned.
363*/367*/
364JAS_DLLEXPORT368JAS_EXPORT
365jas_stream_t *jas_stream_fdopen(int fd, const char *mode);369jas_stream_t *jas_stream_fdopen(int fd, const char *mode);
366 370
371/*!
372@brief Open a stdio (i.e., C standard library) stream as a stream.
373
374@param path
375A pointer to a null-terminated string containing the pathname of the file
376to be reopened.
377@param mode
378A pointer to a null-terminated string containing the mode to be used for
379reopening the file.
380This string is similar to that used by the fdopen function in the
381C standard library.
382@param fp
383A pointer to the `FILE` (i.e., stdio stream) to be reopened.
384
385@details
386It is unspecified whether the open mode specified by mode can be
387changed from the open mode used for opening the stdio stream.
388
389@return
390Upon success, a pointer to the opened stream is returned.
391Otherwise, a null pointer is returned.
392*/
393JAS_EXPORT
394jas_stream_t *jas_stream_freopen(const char *path, const char *mode, FILE *fp);
395
396/*!
397@brief Open a temporary file as a stream.
398
399@details
400A temporary file is created and opened as a stream.
401The temporary file is deleted when closed via jas_stream_close().
402Some operating systems provide a mechanism for ensuring that a file
403is removed when closed.
404Such functionality may be used by the implementation when available.
405
406@return
407Upon success, a pointer to the opened stream is returned.
408Otherwise, a null pointer is returned.
409*/
410JAS_EXPORT
411jas_stream_t *jas_stream_tmpfile(void);
412
367/*!413/*!
368@brief Close a stream.414@brief Close a stream.
369 415
@@ -382,7 +428,7 @@ can fail is due to an I/O error when flushing buffered output. · 12 unmodified lines
382If no errors are encountered when closing the stream, 0 is returned.428If no errors are encountered when closing the stream, 0 is returned.
383Otherwise, a nonzero value is returned.429Otherwise, a nonzero value is returned.
384*/430*/
385JAS_DLLEXPORT431JAS_EXPORT
386int jas_stream_close(jas_stream_t *stream);432int jas_stream_close(jas_stream_t *stream);
387 433
388/******************************************************************************\434/******************************************************************************\
@@ -404,6 +450,7 @@ A nonzero value indicates that the stream has encountered EOF. · 15 unmodified lines
404 450
405/*!451/*!
406@brief Get the error indicator for a stream.452@brief Get the error indicator for a stream.
453
407@param stream454@param stream
408The stream whose error indicator is to be queried.455The stream whose error indicator is to be queried.
409@return456@return
@@ -417,6 +464,7 @@ Note that EOF is not an error. · 7 unmodified lines
417 464
418/*!465/*!
419@brief Clear the error indicator for a stream.466@brief Clear the error indicator for a stream.
467
420@param stream468@param stream
421The stream whose error indicator is to be cleared.469The stream whose error indicator is to be cleared.
422 470
@@ -441,6 +489,7 @@ effectively infinite). · 18 unmodified lines
441 489
442/*!490/*!
443@brief Set the read/write limit for a stream.491@brief Set the read/write limit for a stream.
492
444@param stream493@param stream
445A pointer to the stream whose read/write limit is to be set.494A pointer to the stream whose read/write limit is to be set.
446@param rwlimit495@param rwlimit
@@ -453,7 +502,7 @@ A negative read/write limit is treated as if it were infinity · 6 unmodified lines
453@return502@return
454The old read/write limit is returned.503The old read/write limit is returned.
455*/504*/
456JAS_DLLEXPORT long jas_stream_setrwlimit(jas_stream_t *stream, long rwlimit);505JAS_EXPORT long jas_stream_setrwlimit(jas_stream_t *stream, long rwlimit);
457 506
458/*!507/*!
459@brief Get the read/write count for a stream.508@brief Get the read/write count for a stream.
@@ -470,6 +519,7 @@ This operation cannot fail. · 10 unmodified lines
470 519
471/*!520/*!
472@brief Set the read/write count for a stream.521@brief Set the read/write count for a stream.
522
473@param stream523@param stream
474A pointer to the stream whose read/write count is to be set.524A pointer to the stream whose read/write count is to be set.
475@param rw_count525@param rw_count
@@ -480,7 +530,8 @@ This operation cannot fail. · 4 unmodified lines
480@todo530@todo
481TODO/FIXME: Should this macro evaluate to void?531TODO/FIXME: Should this macro evaluate to void?
482*/532*/
483JAS_DLLEXPORT long jas_stream_setrwcount(jas_stream_t *stream, long rw_count);533JAS_EXPORT
534long jas_stream_setrwcount(jas_stream_t *stream, long rw_count);
484 535
485/******************************************************************************\536/******************************************************************************\
486* Macros/functions for I/O.537* Macros/functions for I/O.
@@ -491,6 +542,13 @@ JAS_DLLEXPORT long jas_stream_setrwcount(jas_stream_t *stream, long rw_count); · 4 unmodified lines
491/*!542/*!
492@brief jas_stream_getc543@brief jas_stream_getc
493Read a character from a stream.544Read a character from a stream.
545
546@param stream
547A pointer to the stream from which to read a character.
548
549@returns
550If a character is succesfully read, the character is returned.
551Otherwise, EOF is returned.
494*/552*/
495#define jas_stream_getc(stream) jas_stream_getc_func(stream)553#define jas_stream_getc(stream) jas_stream_getc_func(stream)
496#else554#else
@@ -502,6 +560,16 @@ Read a character from a stream. · 5 unmodified lines
502/*!560/*!
503@brief jas_stream_putc561@brief jas_stream_putc
504Write a character to a stream.562Write a character to a stream.
563
564@param stream
565A pointer to the stream to which to write the character.
566@param c
567The character to be written.
568
569@returns
570If the character is successfully output, the value of the character is
571returned.
572Otherwise, EOF is returned.
505*/573*/
506#define jas_stream_putc(stream, c) jas_stream_putc_func(stream, c)574#define jas_stream_putc(stream, c) jas_stream_putc_func(stream, c)
507#else575#else
@@ -525,6 +593,9 @@ stream @c stream into the buffer starting at @c buffer. · 17 unmodified lines
525The number of characters read can be less than @c count, due to593The number of characters read can be less than @c count, due to
526end-of-file (EOF) or an I/O error.594end-of-file (EOF) or an I/O error.
527 595
596(This function is analogous to fread with the two read-count
597parameters combined into a single size.)
598
528@return599@return
529The number of characters read is returned.600The number of characters read is returned.
530In the case that the number of characters read is less than @c count,601In the case that the number of characters read is less than @c count,
@@ -535,18 +606,16 @@ to distinguish between: · 4 unmodified lines
535<li>a failure due to the read/write limit being exceeded606<li>a failure due to the read/write limit being exceeded
536<li>EOF.607<li>EOF.
537</ol>608</ol>
538TODO/CHECK: can items 1 and 2 be distinguished currently?609(The functions jas_stream_getrwcount() and jas_stream_getrwlimit()
610can be used to distinguish between failure due to an I/O error
611and failure due to the read/write limit being exceeed.)
539 612
540@warning613@todo
541TODO/FIXME/CHECK: jas_stream_error should be true if RWLIMIT exceeded?614TODO: should jas_stream_error be true if RWLIMIT exceeded?
542or need a jas_stream_rwlimit predicate?615or maybe introduce a jas_stream_rwlimit predicate?
543
544@warning
545TODO/FIXME: In the future, the type of the count parameter and the
546return type will be changed to size_t.
547*/616*/
548JAS_DLLEXPORT617JAS_EXPORT
549unsigned jas_stream_read(jas_stream_t *stream, void *buffer, unsigned count);618size_t jas_stream_read(jas_stream_t *stream, void *buffer, size_t count);
550 619
551/*!620/*!
552@brief Attempt to retrieve one or more pending characters of input621@brief Attempt to retrieve one or more pending characters of input
@@ -569,9 +638,11 @@ Returns the number of bytes copied to the given buffer, or 0 on error · 16 unmodified lines
569or EOF.638or EOF.
570 639
571@warning640@warning
572TODO/FIXME: peeking at EOF should be distinguishable from an I/O error641TODO/FIXME: peeking at EOF should be distinguishable from an I/O error;
642also should return type be changed to size_t?
643
573*/644*/
574JAS_DLLEXPORT645JAS_EXPORT
575unsigned jas_stream_peek(jas_stream_t *stream, void *buffer, size_t count);646unsigned jas_stream_peek(jas_stream_t *stream, void *buffer, size_t count);
576 647
577/*!648/*!
@@ -590,6 +661,9 @@ from the buffer starting at @c buffer to the stream @c stream. · 12 unmodified lines
590The number of characters written can be less than @c count due to661The number of characters written can be less than @c count due to
591an I/O error or the read/write limit being exceeded.662an I/O error or the read/write limit being exceeded.
592 663
664(This function is analogous to fwrite with the two write-count
665parameters combined into a single size.)
666
593@return667@return
594Upon success, the number of characters successfully written is returned.668Upon success, the number of characters successfully written is returned.
595If an error occurs, the value returned will be less than @c count.669If an error occurs, the value returned will be less than @c count.
@@ -599,15 +673,10 @@ of which does not currently exist?) can be used to distinguish between: · 3 unmodified lines
599<li>failure due to an I/O error673<li>failure due to an I/O error
600<li>failure due to the read/write limit being exceeded674<li>failure due to the read/write limit being exceeded
601</ol>675</ol>
602
603@warning
604TODO/FIXME:
605The type of the count parameter should be size_t.
606The return type should be size_t.
607*/676*/
608JAS_DLLEXPORT677JAS_EXPORT
609unsigned jas_stream_write(jas_stream_t *stream, const void *buffer,678size_t jas_stream_write(jas_stream_t *stream, const void *buffer,
610 unsigned count);679 size_t count);
611 680
612/*!681/*!
613@brief Write formatted output to a stream.682@brief Write formatted output to a stream.
@@ -630,7 +699,7 @@ If an error is encountered, a negative value is returned. · 16 unmodified lines
630I think that the return type of int is okay here.699I think that the return type of int is okay here.
631It is consistent with printf and friends.700It is consistent with printf and friends.
632*/701*/
633JAS_DLLEXPORT702JAS_EXPORT
634int jas_stream_printf(jas_stream_t *stream, const char *format, ...);703int jas_stream_printf(jas_stream_t *stream, const char *format, ...);
635 704
636/*!705/*!
@@ -644,11 +713,14 @@ A pointer to a null-terminated string for output. · 7 unmodified lines
644@details713@details
645The null character is not output.714The null character is not output.
646 715
716(This function is analogous to fputs for C standard library streams.)
717
647@return718@return
648Upon success, a nonnegative value is returned.719Upon success, a nonnegative value is returned.
649Upon failure, a negative value is returned.720Upon failure, a negative value is returned.
650*/721*/
651JAS_DLLEXPORT int jas_stream_puts(jas_stream_t *stream, const char *s);722JAS_EXPORT
723int jas_stream_puts(jas_stream_t *stream, const char *s);
652 724
653/*!725/*!
654@brief Read a line of input from a stream.726@brief Read a line of input from a stream.
@@ -666,13 +738,15 @@ If a newline character is read, it is placed in the buffer. · 11 unmodified lines
666Since the buffer may be too small to hold the input,738Since the buffer may be too small to hold the input,
667this operation can fail due to attempted buffer overrun.739this operation can fail due to attempted buffer overrun.
668 740
741(This function is analogous to fgets for C standard library streams.)
742
669@return743@return
670If the operation fails (e.g., due to an I/O error or attempted buffer overrun),744If the operation fails (e.g., due to an I/O error or attempted buffer overrun),
671a null pointer is returned.745a null pointer is returned.
672Otherwise, buffer is returned.746Otherwise, buffer is returned.
673*/747*/
674JAS_DLLEXPORT char *748JAS_EXPORT
675jas_stream_gets(jas_stream_t *stream, char *buffer, int buffer_size);749char *jas_stream_gets(jas_stream_t *stream, char *buffer, int buffer_size);
676 750
677/*!751/*!
678@brief Look at the next character to be read from a stream without actually752@brief Look at the next character to be read from a stream without actually
@@ -719,8 +793,8 @@ The approximate limit is given by the value of JAS_STREAM_MAXPUTBACK. · 40 unmodified lines
719Upon success, zero is returned.793Upon success, zero is returned.
720If the specified character cannot be pushed back, a negative value is returned.794If the specified character cannot be pushed back, a negative value is returned.
721*/795*/
722JAS_DLLEXPORT int796JAS_EXPORT
723jas_stream_ungetc(jas_stream_t *stream, int c);797int jas_stream_ungetc(jas_stream_t *stream, int c);
724 798
725/******************************************************************************\799/******************************************************************************\
726* Macros/functions for getting/setting the stream position.800* Macros/functions for getting/setting the stream position.
@@ -741,7 +815,8 @@ If the underlying file object supports seek operations, a (strictly) · 14 unmodified lines
741positive value is returned.815positive value is returned.
742Otherwise, 0 is returned.816Otherwise, 0 is returned.
743*/817*/
744JAS_ATTRIBUTE_PURE JAS_DLLEXPORT818JAS_EXPORT
819JAS_ATTRIBUTE_PURE
745int jas_stream_isseekable(jas_stream_t *stream);820int jas_stream_isseekable(jas_stream_t *stream);
746 821
747/*!822/*!
@@ -763,37 +838,46 @@ in a similar fashion as the fseek function in the C standard library · 15 unmodified lines
763Upon success, the new stream position is returned.838Upon success, the new stream position is returned.
764Upon failure, a negative value is returned.839Upon failure, a negative value is returned.
765*/840*/
766JAS_DLLEXPORT841JAS_EXPORT
767long jas_stream_seek(jas_stream_t *stream, long offset, int origin);842long jas_stream_seek(jas_stream_t *stream, long offset, int origin);
768 843
769/*!844/*!
770@brief Get the current position within the stream.845@brief Get the current position within the stream.
846
771@param stream847@param stream
772A pointer to the stream whose current position is to be queried.848A pointer to the stream whose current position is to be queried.
773 849
774@details850@details
775The current position of the stream is returned.851The current position of the stream is returned.
776 852
853(This function is analogous to ftell for C standard library streams.)
854
777@return855@return
778Upon success, the current stream position is returned.856Upon success, the current stream position is returned.
779If an error is encountered, a negative value is returned.857If an error is encountered, a negative value is returned.
780*/858*/
781JAS_ATTRIBUTE_PURE JAS_DLLEXPORT859JAS_EXPORT
782long jas_stream_tell(jas_stream_t *stream);860long jas_stream_tell(jas_stream_t *stream);
783 861
784/*!862/*!
785@brief Seek to the beginning of a stream.863@brief Seek to the beginning of a stream.
864
786@param stream865@param stream
787A pointer to the stream whose position is to be set.866A pointer to the stream whose position is to be set.
867
788@details868@details
789The stream position is set to the start of the stream.869The stream position is set to the start of the stream.
790This function is equivalent to returning the value870This function is equivalent to returning the value
791of jas_stream_seek(stream, 0, SEEK_SET).871of jas_stream_seek(stream, 0, SEEK_SET).
872
873(This function is analogous to frewind for C standard library streams.)
874
792@return875@return
793Upon success, the new stream position is returned.876Upon success, the new stream position is returned.
794Otherwise, a negative value is returned.877Otherwise, a negative value is returned.
795*/878*/
796JAS_DLLEXPORT int jas_stream_rewind(jas_stream_t *stream);879JAS_EXPORT
880int jas_stream_rewind(jas_stream_t *stream);
797 881
798/******************************************************************************\882/******************************************************************************\
799* Macros/functions for flushing.883* Macros/functions for flushing.
@@ -801,15 +885,21 @@ JAS_DLLEXPORT int jas_stream_rewind(jas_stream_t *stream); · 1 unmodified line
801 885
802/*!886/*!
803@brief Flush any pending output to a stream.887@brief Flush any pending output to a stream.
888
804@param stream889@param stream
805A pointer to the stream for which output should be flushed.890A pointer to the stream for which output should be flushed.
891
806@details892@details
807The function flushes any buffered output to the underlying file object.893The function flushes any buffered output to the underlying file object.
894
895(This function is analogous to fflush for C standard library streams.)
896
808@return897@return
809Upon success, zero is returned.898Upon success, zero is returned.
810Otherwise, a negative value is returned.899Otherwise, a negative value is returned.
811*/900*/
812JAS_DLLEXPORT int jas_stream_flush(jas_stream_t *stream);901JAS_EXPORT
902int jas_stream_flush(jas_stream_t *stream);
813 903
814/******************************************************************************\904/******************************************************************************\
815* Miscellaneous macros/functions.905* Miscellaneous macros/functions.
@@ -828,14 +918,50 @@ The number of characters to copy. · 12 unmodified lines
828@details918@details
829The function copies the specified number of characters from the919The function copies the specified number of characters from the
830source stream to the destination stream.920source stream to the destination stream.
921In particular, if @c count is nonnegative, @c count characters are
922copied from the source stream @c source to the destination stream
923@c destination.
924Otherwise (i.e., if @c count is negative), the entire source
925stream @c source (i.e., until EOF is reached) is copied to the
926destination stream @c destination.
831 927
832@return928@return
833Upon success, 0 is returned; otherwise, -1 is returned.929Upon success, 0 is returned; otherwise, -1 is returned.
834 930
835@todo931@todo
836TODO/FIXME: count should probably be a size_t; return type ssize_t?932TODO/FIXME: should return type be ssize_t and the return value be
933the count of the characters copied?
934Perhaps, it might be safer to introduce a new function with differing
935semantics and deprecate this one?
837*/936*/
838JAS_DLLEXPORT int jas_stream_copy(jas_stream_t *destination, jas_stream_t *source, int count);937JAS_EXPORT
938int jas_stream_copy(jas_stream_t *destination, jas_stream_t *source,
939 ssize_t count);
940
941/*!
942@brief Print a hex dump of data read from a stream.
943
944@param stream
945A pointer to the stream from which to read data.
946@param fp
947A pointer to a stdio stream (i.e., FILE) to which to print the hex dump.
948@param count
949The number of characters to include in the hex dump.
950
951@details
952This function prints a hex dump of data read from a stream to a
953stdio stream.
954This function is most likely to be useful for debugging.
955
956@return
957Upon success, 0 is returned.
958Otherwise, a negative value is returned.
959
960@todo
961TODO/FIXME: should count be unsigned int or size_t instead of int?
962*/
963JAS_EXPORT
964int jas_stream_display(jas_stream_t *stream, FILE *fp, int count);
839 965
840/*!966/*!
841@brief Consume (i.e., discard) characters from stream.967@brief Consume (i.e., discard) characters from stream.
@@ -855,11 +981,9 @@ If an error or EOF is encountered, the number of characters read · 13 unmodified lines
855will be less than count.981will be less than count.
856To distinguish EOF from an I/O error, jas_stream_eof() and jas_stream_error()982To distinguish EOF from an I/O error, jas_stream_eof() and jas_stream_error()
857can be used.983can be used.
858
859@warning
860TODO/FIXME: count be size_t and return type should be ssize_t
861*/984*/
862JAS_DLLEXPORT int jas_stream_gobble(jas_stream_t *stream, int count);985JAS_EXPORT
986ssize_t jas_stream_gobble(jas_stream_t *stream, size_t count);
863 987
864/*!988/*!
865@brief Write a fill character multiple times to a stream.989@brief Write a fill character multiple times to a stream.
@@ -881,16 +1005,15 @@ The number of times the fill character was written to the stream is · 15 unmodified lines
881returned.1005returned.
882If this value is less than the specified count, an error must have1006If this value is less than the specified count, an error must have
883occurred.1007occurred.
884
885@todo
886TODO: should the count be size_t; return type maybe size_t?
887*/1008*/
888JAS_DLLEXPORT int jas_stream_pad(jas_stream_t *stream, int count, int value);1009JAS_EXPORT
1010ssize_t jas_stream_pad(jas_stream_t *stream, size_t count, int value);
889 1011
890/*!1012/*!
891@brief Get the size of the file associated with the specified stream.1013@brief Get the size of the file associated with the specified stream.
892 1014
893@param stream1015@param stream
1016A pointer to the stream.
894 1017
895@details1018@details
896This function queries the size (i.e., length) of the underlying file object1019This function queries the size (i.e., length) of the underlying file object
@@ -901,10 +1024,11 @@ The specified stream must be seekable. · 4 unmodified lines
901Upon success, the size of the stream is returned.1024Upon success, the size of the stream is returned.
902If an error occurs, a negative value is returned.1025If an error occurs, a negative value is returned.
903 1026
904@warning1027@todo
905TODO/FIXME: the return type should be ssize_t?1028Should the return type be long or ssize_t? long is consistent with the
1029type used for seek offsets.
906*/1030*/
907JAS_ATTRIBUTE_PURE JAS_DLLEXPORT1031JAS_EXPORT
908long jas_stream_length(jas_stream_t *stream);1032long jas_stream_length(jas_stream_t *stream);
909 1033
910/******************************************************************************\1034/******************************************************************************\
@@ -917,10 +1041,10 @@ directly, you will die a horrible, miserable, and painful death! */ · 6 unmodified lines
917/* These prototypes need to be here for the sake of the stream_getc and1041/* These prototypes need to be here for the sake of the stream_getc and
918stream_putc macros. */1042stream_putc macros. */
919/* Library users must not invoke these functions directly. */1043/* Library users must not invoke these functions directly. */
920JAS_DLLEXPORT int jas_stream_fillbuf(jas_stream_t *stream, int getflag);1044JAS_EXPORT int jas_stream_fillbuf(jas_stream_t *stream, int getflag);
921JAS_DLLEXPORT int jas_stream_flushbuf(jas_stream_t *stream, int c);1045JAS_EXPORT int jas_stream_flushbuf(jas_stream_t *stream, int c);
922JAS_DLLEXPORT int jas_stream_getc_func(jas_stream_t *stream);1046JAS_EXPORT int jas_stream_getc_func(jas_stream_t *stream);
923JAS_DLLEXPORT int jas_stream_putc_func(jas_stream_t *stream, int c);1047JAS_EXPORT int jas_stream_putc_func(jas_stream_t *stream, int c);
924 1048
925/* Read a character from a stream. */1049/* Read a character from a stream. */
926static inline int jas_stream_getc2(jas_stream_t *stream)1050static inline int jas_stream_getc2(jas_stream_t *stream)
jasper/jas_string.h+150−0
@@ -0,0 +1,150 @@
1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2002 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64/*!
65 * @file jas_string.h
66 * @brief String Library
67 */
68
69#ifndef JAS_STRING_H
70#define JAS_STRING_H
71
72/******************************************************************************\
73* Includes.
74\******************************************************************************/
75
76/* The configuration header file should be included first. */
77#include <jasper/jas_config.h>
78
79#include <jasper/jas_types.h>
80
81#ifdef __cplusplus
82extern "C" {
83#endif
84
85/*!
86 * @addtogroup module_string
87 * @{
88 */
89
90/******************************************************************************\
91* Functions.
92\******************************************************************************/
93
94/*!
95@brief
96Create a copy of a null-terminated string.
97
98@details
99This function has a behavior similar to the well-known strdup function.
100*/
101JAS_EXPORT
102char *jas_strdup(const char *);
103
104/*!
105@brief
106Extract tokens from a string.
107
108@details
109This function has a similar behavior as @c strtok_r in the POSIX standard.
110*/
111JAS_EXPORT
112char *jas_strtok(char *str, const char *delim, char **saveptr);
113
114/*!
115@brief
116Split a string into tokens based on specified delimiters.
117
118@param string
119A pointer to a null-terminated string to be split into tokens.
120@param delim
121A pointer to a null-terminated string contained characters used to delimit
122tokens.
123@param tokens_buf
124A pointer to the output token array.
125@param max_tokens_buf
126A pointer to the allocated size of the token array.
127@param num_tokens_buf
128A pointer to the number of elements in the token array.
129
130@details
131The memory to hold token information is allocated via jas_malloc()
132and friends.
133
134@returns
135If successful, zero is returned.
136Otherwise, a nonzero value is returned.
137*/
138JAS_EXPORT
139int jas_stringtokenize(const char *string, const char *delim,
140 char ***tokens_buf, size_t *max_tokens_buf, size_t *num_tokens_buf);
141
142/*!
143 * @}
144 */
145
146#ifdef __cplusplus
147}
148#endif
149
150#endif
jasper/jas_thread.h+795−0
@@ -0,0 +1,795 @@
1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2003 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64/*!
65 * @file jas_thread.h
66 * @brief Threads
67 */
68
69#ifndef JAS_THREAD_H
70#define JAS_THREAD_H
71
72/******************************************************************************\
73* Includes
74\******************************************************************************/
75
76/* The configuration header file should be included first. */
77#include <jasper/jas_config.h>
78
79#include "jasper/jas_compiler.h"
80#include "jasper/jas_types.h"
81
82#if defined(JAS_THREADS)
83
84#include <stdlib.h>
85#include <assert.h>
86
87#if defined(JAS_THREADS_C11)
88#include <threads.h>
89#include <stdatomic.h>
90#elif defined(JAS_THREADS_PTHREAD)
91#include <pthread.h>
92#include <sched.h>
93#elif defined(JAS_THREADS_WIN32)
94#include <process.h>
95#include <windows.h>
96#include <processthreadsapi.h>
97#endif
98
99#endif
100
101/******************************************************************************\
102\******************************************************************************/
103
104#ifdef __cplusplus
105extern "C" {
106#endif
107
108/*!
109 * @cond DOXYGEN_EXCLUDE
110 * @addtogroup module_threads
111 * @{
112 */
113
114#if defined(JAS_THREADS)
115#if defined(JAS_FOR_INTERNAL_USE_ONLY) || defined(JAS_FOR_JASPER_APP_USE_ONLY)
116
117/******************************************************************************\
118* Types
119\******************************************************************************/
120
121#if defined(JAS_THREADS_C11)
122# define JAS_THREADS_IMPL "C11"
123# define JAS_USE_SPINLOCK
124#elif defined(JAS_THREADS_PTHREAD)
125# define JAS_THREADS_IMPL "PTHREAD"
126# undef JAS_USE_SPINLOCK
127#elif defined(JAS_THREADS_WIN32)
128# define JAS_THREADS_IMPL "WIN32"
129# define JAS_USE_SPINLOCK
130#endif
131
132/**************************************\
133* Spinlock
134\**************************************/
135
136/*! Spinlock type. */
137#if defined(JAS_THREADS_C11)
138# define JAS_USE_SPINLOCK
139typedef struct {
140 atomic_flag flag;
141} jas_spinlock_t;
142#elif defined(JAS_THREADS_PTHREAD)
143/* There is no pthread_spinlock_t type on MacOS. */
144# undef JAS_USE_SPINLOCK
145#elif defined(JAS_THREADS_WIN32)
146# define JAS_USE_SPINLOCK
147typedef struct {
148 LONG flag;
149} jas_spinlock_t;
150#endif
151
152/*! Spinlock initializer. */
153#if defined(JAS_THREADS_C11)
154#define JAS_SPINLOCK_INITIALIZER {ATOMIC_FLAG_INIT}
155#elif defined(JAS_THREADS_PTHREAD)
156/* There is no pthread_spinlock_t type on MacOS. */
157#elif defined(JAS_THREADS_WIN32)
158#define JAS_SPINLOCK_INITIALIZER {0}
159#endif
160
161/**************************************\
162* Basic Mutex
163\**************************************/
164
165/*! Mutex type. */
166#if defined(JAS_THREADS_C11)
167typedef mtx_t jas_basicmutex_t;
168#elif defined(JAS_THREADS_PTHREAD)
169typedef pthread_mutex_t jas_basicmutex_t;
170#elif defined(JAS_THREADS_WIN32)
171typedef CRITICAL_SECTION jas_basicmutex_t;
172#endif
173
174/*! Mutex initializer. */
175#if defined(JAS_THREADS_C11)
176#undef JAS_BASICMUTEX_INITIALIZER
177#elif defined(JAS_THREADS_PTHREAD)
178#define JAS_BASICMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
179#elif defined(JAS_THREADS_WIN32)
180#define JAS_BASICMUTEX_INITIALIZER
181#endif
182
183/**************************************\
184* Mutex (Allowing Static Initialization)
185\**************************************/
186
187#if defined(JAS_USE_SPINLOCK)
188# define jas_mutex_t jas_spinlock_t
189# define JAS_MUTEX_INITIALIZER JAS_SPINLOCK_INITIALIZER
190# define jas_mutex_init jas_spinlock_init
191# define jas_mutex_cleanup jas_spinlock_cleanup
192# define jas_mutex_lock jas_spinlock_lock
193# define jas_mutex_unlock jas_spinlock_unlock
194#else
195# define jas_mutex_t jas_basicmutex_t
196# define JAS_MUTEX_INITIALIZER JAS_BASICMUTEX_INITIALIZER
197# define jas_mutex_init jas_basicmutex_init
198# define jas_mutex_cleanup jas_basicmutex_cleanup
199# define jas_mutex_lock jas_basicmutex_lock
200# define jas_mutex_unlock jas_basicmutex_unlock
201#endif
202
203/**************************************\
204* Once Flag
205\**************************************/
206
207/*! Once-flag type. */
208#if defined(JAS_THREADS_C11)
209typedef once_flag jas_once_flag_t;
210#elif defined(JAS_THREADS_PTHREAD)
211typedef pthread_once_t jas_once_flag_t;
212#elif defined(JAS_THREADS_WIN32)
213typedef struct {
214 volatile LONG status;
215} jas_once_flag_t;
216#endif
217
218/*! Once-flag initializer. */
219#if defined(JAS_THREADS_C11)
220# define JAS_ONCE_FLAG_INIT ONCE_FLAG_INIT
221#elif defined(JAS_THREADS_PTHREAD)
222# define JAS_ONCE_FLAG_INIT PTHREAD_ONCE_INIT
223#elif defined(JAS_THREADS_WIN32)
224# define JAS_ONCE_FLAG_INIT {0}
225#endif
226
227/**************************************\
228* Threads
229\**************************************/
230
231#if defined(JAS_FOR_INTERNAL_USE_ONLY) || defined(JAS_FOR_JASPER_APP_USE_ONLY)
232
233/*! Thread ID type. */
234#if defined(JAS_THREADS_C11)
235typedef thrd_t jas_thread_id_t;
236#elif defined(JAS_THREADS_PTHREAD)
237typedef pthread_t jas_thread_id_t;
238#elif defined(JAS_THREADS_WIN32)
239typedef HANDLE jas_thread_id_t;
240#endif
241
242/*! Thread type. */
243#if defined(JAS_THREADS_C11)
244typedef thrd_t jas_thread_t;
245#elif defined(JAS_THREADS_PTHREAD)
246typedef struct {
247 pthread_t id;
248 int (*func)(void *);
249 void *arg;
250 int result;
251} jas_thread_t;
252#elif defined(JAS_THREADS_WIN32)
253typedef struct {
254 jas_thread_id_t id;
255 int (*func)(void *);
256 void *arg;
257} jas_thread_t;
258#endif
259
260static inline void jas_thread_yield(void);
261
262#endif
263
264/**************************************\
265* Thread-Specific Storage (TSS)
266\**************************************/
267
268/*! Thread-specific storage type. */
269#if defined(JAS_THREADS_C11)
270typedef tss_t jas_tss_t;
271#elif defined(JAS_THREADS_PTHREAD)
272typedef pthread_key_t jas_tss_t;
273#elif defined(JAS_THREADS_WIN32)
274typedef DWORD jas_tss_t;
275#endif
276
277
278/******************************************************************************\
279* Spinlock
280\******************************************************************************/
281
282#if defined(JAS_USE_SPINLOCK)
283
284/*!
285@brief
286Initialize a spinlock.
287
288@param mtx
289A pointer to the spinlock to be initialized.
290
291@returns
292If the spinlock is successfully initialized, zero is returned.
293Otherwise, a nonzero value is returned.
294*/
295static inline int jas_spinlock_init(jas_spinlock_t *mtx)
296{
297 assert(mtx);
298#if defined(JAS_THREADS_C11)
299 atomic_flag_clear(&mtx->flag);
300 return 0;
301#elif defined(JAS_THREADS_PTHREAD)
302 JAS_UNUSED(mtx);
303 abort();
304 return -1;
305#elif defined(JAS_THREADS_WIN32)
306 InterlockedExchange(&mtx->flag, 0);
307 return 0;
308#endif
309}
310
311/*!
312@brief
313Clean up a spinlock mutex.
314
315@param mtx
316A pointer to the spinlock to be cleaned up.
317
318@returns
319If the spinlock is successfully cleaned up, zero is returned.
320Otherwise, a nonzero value is returned.
321*/
322static inline int jas_spinlock_cleanup(jas_spinlock_t *mtx)
323{
324 assert(mtx);
325#if defined(JAS_THREADS_C11)
326 JAS_UNUSED(mtx);
327 return 0;
328#elif defined(JAS_THREADS_PTHREAD)
329 JAS_UNUSED(mtx);
330 abort();
331 return -1;
332#elif defined(JAS_THREADS_WIN32)
333 JAS_UNUSED(mtx);
334 return 0;
335#endif
336}
337
338/*!
339@brief
340Acquire a spinlock.
341
342@param mtx
343A pointer to the spinlock to be acquired.
344
345@returns
346If successful, zero is returned.
347Otherwise, a nonzero value is returned.
348*/
349static inline int jas_spinlock_lock(jas_spinlock_t *mtx)
350{
351 assert(mtx);
352#if defined(JAS_THREADS_C11)
353 while (atomic_flag_test_and_set(&mtx->flag)) {}
354 return 0;
355#elif defined(JAS_THREADS_PTHREAD)
356 JAS_UNUSED(mtx);
357 abort();
358 return -1;
359#elif defined(JAS_THREADS_WIN32)
360 while (InterlockedCompareExchange(&mtx->flag, 1, 0)) {}
361 return 0;
362#endif
363}
364
365/*!
366@brief
367Release a spinlock.
368
369@param mtx
370A pointer to the spinlock to be released.
371
372@returns
373If the operation is successful, zero is returned.
374Otherwise, a nonzero value is returned.
375*/
376static inline int jas_spinlock_unlock(jas_spinlock_t *mtx)
377{
378 assert(mtx);
379#if defined(JAS_THREADS_C11)
380 atomic_flag_clear(&mtx->flag);
381 return 0;
382#elif defined(JAS_THREADS_PTHREAD)
383 JAS_UNUSED(mtx);
384 abort();
385 return -1;
386#elif defined(JAS_THREADS_WIN32)
387 InterlockedExchange(&mtx->flag, 0);
388 return 0;
389#endif
390}
391
392#endif
393
394/******************************************************************************\
395* Basic Mutex
396\******************************************************************************/
397
398/* For internal use only. */
399static inline int jas_basicmutex_init(jas_basicmutex_t *mtx)
400{
401 assert(mtx);
402#if defined(JAS_THREADS_C11)
403 return mtx_init(mtx, mtx_plain) == thrd_success ? 0 : -1;
404#elif defined(JAS_THREADS_PTHREAD)
405 return pthread_mutex_init(mtx, 0);
406#elif defined(JAS_THREADS_WIN32)
407 InitializeCriticalSection(mtx);
408 return 0;
409#endif
410}
411
412/* For internal use only. */
413static inline int jas_basicmutex_cleanup(jas_basicmutex_t *mtx)
414{
415 assert(mtx);
416#if defined(JAS_THREADS_C11)
417 mtx_destroy(mtx);
418 return 0;
419#elif defined(JAS_THREADS_PTHREAD)
420 return pthread_mutex_destroy(mtx);
421#elif defined(JAS_THREADS_WIN32)
422 DeleteCriticalSection(mtx);
423 return 0;
424#endif
425}
426
427/* For internal use only. */
428static inline int jas_basicmutex_lock(jas_basicmutex_t *mtx)
429{
430 assert(mtx);
431#if defined(JAS_THREADS_C11)
432 return mtx_lock(mtx);
433#elif defined(JAS_THREADS_PTHREAD)
434 return pthread_mutex_lock(mtx);
435#elif defined(JAS_THREADS_WIN32)
436 EnterCriticalSection(mtx);
437 return 0;
438#endif
439}
440
441/* For internal use only. */
442static inline int jas_basicmutex_unlock(jas_basicmutex_t *mtx)
443{
444 assert(mtx);
445#if defined(JAS_THREADS_C11)
446 return mtx_unlock(mtx);
447#elif defined(JAS_THREADS_PTHREAD)
448 return pthread_mutex_unlock(mtx);
449#elif defined(JAS_THREADS_WIN32)
450 LeaveCriticalSection(mtx);
451 return 0;
452#endif
453}
454
455/******************************************************************************\
456* Thread-Specific Storage (TSS)
457\******************************************************************************/
458
459/*!
460@brief
461Create thread-specific storage.
462
463@param tss
464A pointer to the TSS object to be initialized.
465@param destructor
466A function to be called when the TSS is deallocated when the thread exits.
467
468@returns
469If the operation is successful, zero is returned.
470Otherwise, a nonzero value is returned.
471*/
472static inline
473int jas_tss_create(jas_tss_t *tss, void (*destructor)(void *))
474{
475 assert(tss);
476#if defined(JAS_THREADS_C11)
477 return tss_create(tss, destructor) == thrd_success ? 0 : -1;
478#elif defined(JAS_THREADS_PTHREAD)
479 return pthread_key_create(tss, destructor);
480#elif defined(JAS_THREADS_WIN32)
481 if (destructor) {
482 return -1;
483 }
484 DWORD id;
485 if ((id = TlsAlloc()) == TLS_OUT_OF_INDEXES) {
486 return -2;
487 }
488 *tss = id;
489 return 0;
490#endif
491}
492
493/*!
494@brief Delete thread-specific storage.
495
496@param tss
497The TSS to be destroyed.
498
499@returns
500If the operation is successful, zero is returned.
501Otherwise, a nonzero value is returned.
502*/
503static inline
504void jas_tss_delete(jas_tss_t tss)
505{
506#if defined(JAS_THREADS_C11)
507 tss_delete(tss);
508#elif defined(JAS_THREADS_PTHREAD)
509 pthread_key_delete(tss);
510#elif defined(JAS_THREADS_WIN32)
511 TlsFree(tss);
512#endif
513}
514
515/*!
516@brief Get the thread-specific storage instance for the calling thread.
517
518@param tss
519The TSS to be queried.
520
521@returns
522A pointer to the TSS is returned.
523*/
524static inline
525void *jas_tss_get(jas_tss_t tss)
526{
527#if defined(JAS_THREADS_C11)
528 return tss_get(tss);
529#elif defined(JAS_THREADS_PTHREAD)
530 return pthread_getspecific(tss);
531#elif defined(JAS_THREADS_WIN32)
532 return TlsGetValue(tss);
533#endif
534}
535
536/*!
537@brief Set the thread-specific storage instance for the calling thread.
538
539@param tss
540The TSS object.
541
542@returns
543If the operation is successful, zero is returned.
544Otherwise, a nonzero value is returned.
545*/
546static inline
547int jas_tss_set(jas_tss_t tss, void *value)
548{
549#if defined(JAS_THREADS_C11)
550 return tss_set(tss, value) == thrd_success ? 0 : -1;
551#elif defined(JAS_THREADS_PTHREAD)
552 return pthread_setspecific(tss, value);
553#elif defined(JAS_THREADS_WIN32)
554 return TlsSetValue(tss, value) ? 0 : -1;
555#endif
556}
557
558/******************************************************************************\
559* Once Flag
560\******************************************************************************/
561
562/*!
563@brief Register to call a function once.
564
565@param flag
566A pointer to a flag to track whether the function has been called yet.
567@param func
568A pointer to the function to be called.
569
570@returns
571*/
572static inline int jas_call_once(jas_once_flag_t *flag, void (*func)(void))
573{
574 assert(flag);
575 assert(func);
576#if defined(JAS_THREADS_C11)
577 call_once(flag, func);
578 return 0;
579#elif defined(JAS_THREADS_PTHREAD)
580 return pthread_once(flag, func);
581#elif defined(JAS_THREADS_WIN32)
582 if (InterlockedCompareExchange(&flag->status, 1, 0) == 0) {
583 (func)();
584 InterlockedExchange(&flag->status, 2);
585 } else {
586 while (flag->status == 1) {
587 /* Perform a busy wait. This is ugly. */
588 /* Yield processor. */
589 SwitchToThread();
590 }
591 }
592 return 0;
593#endif
594}
595
596/******************************************************************************\
597* Threads
598\******************************************************************************/
599
600#if defined(JAS_FOR_INTERNAL_USE_ONLY) || defined(JAS_FOR_JASPER_APP_USE_ONLY)
601
602#if defined(JAS_THREADS_PTHREAD)
603static void *thread_func_wrapper(void *thread_ptr)
604{
605 jas_thread_t *thread = JAS_CAST(jas_thread_t *, thread_ptr);
606 int result = (thread->func)(thread->arg);
607 thread->result = result;
608 return thread;
609}
610#elif defined(JAS_THREADS_WIN32)
611static unsigned __stdcall thread_func_wrapper(void *thread_ptr)
612{
613 jas_thread_t *thread = JAS_CAST(jas_thread_t *, thread_ptr);
614 int result = (thread->func)(thread->arg);
615 return JAS_CAST(unsigned, result);
616}
617#endif
618
619/*!
620@brief Compare two thread IDs.
621
622@warning
623This function is only for internal use by the JasPer software.
624This function may be changed/removed without any notice in future versions
625of JasPer.
626*/
627static inline
628int jas_thread_compare(jas_thread_id_t x, jas_thread_id_t y)
629{
630#if defined(JAS_THREADS_C11)
631 return thrd_equal(x, y);
632#elif defined(JAS_THREADS_PTHREAD)
633 return pthread_equal(x, y);
634#elif defined(JAS_THREADS_WIN32)
635 return GetThreadId(x) == GetThreadId(y);
636#endif
637}
638
639/*!
640@brief Create a thread.
641
642@warning
643This function is only for internal use by the JasPer software.
644This function may be changed/removed without any notice in future versions
645of JasPer.
646*/
647static inline
648int jas_thread_create(jas_thread_t *thread, int (*func)(void *), void *arg)
649{
650 assert(thread);
651 assert(func);
652#if defined(JAS_THREADS_C11)
653 return thrd_create(thread, func, arg) == thrd_success ? 0 : -1;
654#elif defined(JAS_THREADS_PTHREAD)
655 thread->func = func;
656 thread->arg = arg;
657 thread->result = 0;
658 return pthread_create(&thread->id, 0, thread_func_wrapper, thread);
659#elif defined(JAS_THREADS_WIN32)
660 uintptr_t handle;
661 thread->func = func;
662 thread->arg = arg;
663 if (!(handle = _beginthreadex(0, 0, thread_func_wrapper, thread, 0, 0))) {
664 return -1;
665 }
666 thread->id = JAS_CAST(jas_thread_id_t, handle);
667 return 0;
668#endif
669}
670
671/*!
672@brief Join a thread.
673
674@warning
675This function is only for internal use by the JasPer software.
676This function may be changed/removed without any notice in future versions
677of JasPer.
678*/
679static inline
680int jas_thread_join(jas_thread_t *thread, int *result)
681{
682 assert(thread);
683#if defined(JAS_THREADS_C11)
684 return thrd_join(*thread, result) == thrd_success ? 0 : -1;
685#elif defined(JAS_THREADS_PTHREAD)
686 void *result_buf;
687 int ret = pthread_join(thread->id, &result_buf);
688 if (!ret) {
689 jas_thread_t *other_thread = JAS_CAST(jas_thread_t *, result_buf);
690 if (result) {
691 /* A null pointer is probably a bug. */
692 assert(other_thread);
693 *result = other_thread ? other_thread->result : 0;
694 }
695 }
696 return ret;
697#elif defined(JAS_THREADS_WIN32)
698 DWORD w;
699 DWORD code;
700 if ((w = WaitForSingleObject(thread->id, INFINITE)) != WAIT_OBJECT_0) {
701 return -1;
702 }
703 if (result) {
704 if (!GetExitCodeThread(thread->id, &code)) {
705 CloseHandle(thread->id);
706 return -1;
707 }
708 *result = JAS_CAST(int, code);
709 }
710 CloseHandle(thread->id);
711 return 0;
712#endif
713}
714
715/*!
716@brief
717Yield the processor.
718
719@warning
720This function is only for internal use by the JasPer software.
721This function may be changed/removed without any notice in future versions
722of JasPer.
723*/
724
725static inline void jas_thread_yield(void)
726{
727#if defined(JAS_THREADS_C11)
728 thrd_yield();
729#elif defined(JAS_THREADS_PTHREAD)
730 sched_yield();
731#elif defined(JAS_THREADS_WIN32)
732 SwitchToThread();
733#endif
734}
735
736#if 0
737/* This functionality is not available for all threading support libraries. */
738static inline
739void jas_thread_exit(int result)
740{
741#if defined(JAS_THREADS_C11)
742 thrd_exit(result);
743#elif defined(JAS_THREADS_PTHREAD)
744 /* This does not have a trivial implementation, as far as I can see. */
745 /* There is no jas_thread_find function. */
746 jas_thread_t *thread = jas_thread_find(pthread_self());
747 thread->result = result;
748 pthread_exit(JAS_CAST(void *, thread));
749#endif
750}
751#endif
752
753#if 0
754/*!
755@brief Get the ID of the calling thread.
756*/
757static inline
758jas_thread_id_t jas_thread_current(void)
759{
760#if defined(JAS_THREADS_C11)
761 return thrd_current();
762#elif defined(JAS_THREADS_PTHREAD)
763 return pthread_self();
764#elif defined(JAS_THREADS_WIN32)
765 /* FIXME - NOT YET IMPLEMENTED. */
766 abort();
767#endif
768}
769#endif
770
771#endif
772
773/******************************************************************************\
774*
775\******************************************************************************/
776
777#endif
778#else
779
780/******************************************************************************\
781* No Threading Support.
782\******************************************************************************/
783
784#endif
785
786/*!
787 * @}
788 * @endcond
789 */
790
791#ifdef __cplusplus
792}
793#endif
794
795#endif
jasper/jas_tvp.h+200−0
@@ -0,0 +1,200 @@
1/*
2 * Copyright (c) 2001-2002 Michael David Adams.
3 * All rights reserved.
4 */
5
6/* __START_OF_JASPER_LICENSE__
7 *
8 * JasPer License Version 2.0
9 *
10 * Copyright (c) 2001-2006 Michael David Adams
11 * Copyright (c) 1999-2000 Image Power, Inc.
12 * Copyright (c) 1999-2000 The University of British Columbia
13 *
14 * All rights reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person (the
17 * "User") obtaining a copy of this software and associated documentation
18 * files (the "Software"), to deal in the Software without restriction,
19 * including without limitation the rights to use, copy, modify, merge,
20 * publish, distribute, and/or sell copies of the Software, and to permit
21 * persons to whom the Software is furnished to do so, subject to the
22 * following conditions:
23 *
24 * 1. The above copyright notices and this permission notice (which
25 * includes the disclaimer below) shall be included in all copies or
26 * substantial portions of the Software.
27 *
28 * 2. The name of a copyright holder shall not be used to endorse or
29 * promote products derived from the Software without specific prior
30 * written permission.
31 *
32 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
33 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
34 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
35 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
37 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
38 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
39 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
40 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
41 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
42 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
43 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
44 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
45 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
46 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
47 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
48 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
49 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
50 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
51 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
52 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
53 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
54 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
55 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
56 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
57 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
58 *
59 * __END_OF_JASPER_LICENSE__
60 */
61
62/*!
63 * @file jas_tvp.h
64 * @brief Tag/Value Pair Parser
65 */
66
67#ifndef JAS_TVP_H
68#define JAS_TVP_H
69
70/******************************************************************************\
71* Includes.
72\******************************************************************************/
73
74/* The configuration header file should be included first. */
75#include <jasper/jas_config.h>
76
77#ifdef __cplusplus
78extern "C" {
79#endif
80
81/*!
82 * @addtogroup module_tvp
83 * @{
84 */
85
86/******************************************************************************\
87* Types.
88\******************************************************************************/
89
90/*!
91@brief
92Tag information type.
93*/
94typedef struct {
95
96 int id;
97 /* The ID for the tag. */
98
99 const char *name;
100 /* The name of the tag. */
101
102} jas_taginfo_t;
103
104/*!
105@brief
106Tag-value parser type.
107*/
108typedef struct {
109
110 char *buf;
111 /* The parsing buffer. */
112
113 char *tag;
114 /* The current tag name. */
115
116 const char *val;
117 /* The current value. */
118
119 char *pos;
120 /* The current position in the parsing buffer. */
121
122} jas_tvparser_t;
123
124/******************************************************************************\
125* Tag information functions.
126\******************************************************************************/
127
128/*!
129@brief
130Lookup a tag by name.
131*/
132JAS_ATTRIBUTE_PURE
133JAS_EXPORT
134const jas_taginfo_t *jas_taginfos_lookup(const jas_taginfo_t *taginfos,
135 const char *name);
136
137/*!
138@brief
139Ensure a nonnull taginfo pointer.
140
141@details
142This function returns a pointer to the specified taginfo object if it
143 exists (i.e., the pointer is nonnull); otherwise, a pointer to a dummy
144 object is returned. This is useful in some situations to avoid checking
145 for a null pointer.
146*/
147JAS_ATTRIBUTE_PURE
148JAS_EXPORT
149const jas_taginfo_t *jas_taginfo_nonull(const jas_taginfo_t *taginfo);
150
151/******************************************************************************\
152* Tag-value parser functions.
153\******************************************************************************/
154
155/*!
156@brief
157Create a tag-value parser for the specified string.
158*/
159JAS_EXPORT
160jas_tvparser_t *jas_tvparser_create(const char *s);
161
162/*!
163@brief
164Destroy a tag-value parser.
165*/
166JAS_EXPORT
167void jas_tvparser_destroy(jas_tvparser_t *tvparser);
168
169/*!
170@brief
171Get the next tag-value pair.
172*/
173JAS_EXPORT
174int jas_tvparser_next(jas_tvparser_t *tvparser);
175
176/*!
177@brief
178Get the tag name for the current tag-value pair.
179*/
180JAS_ATTRIBUTE_PURE
181JAS_EXPORT
182const char *jas_tvparser_gettag(const jas_tvparser_t *tvparser);
183
184/*!
185@brief
186Get the value for the current tag-value pair.
187*/
188JAS_ATTRIBUTE_PURE
189JAS_EXPORT
190const char *jas_tvparser_getval(const jas_tvparser_t *tvparser);
191
192/*!
193 * @}
194 */
195
196#ifdef __cplusplus
197}
198#endif
199
200#endif
jasper/jas_types.h+109−35
@@ -72,47 +72,71 @@ · 71 unmodified lines
72/* The configuration header file should be included first. */72/* The configuration header file should be included first. */
73#include <jasper/jas_config.h>73#include <jasper/jas_config.h>
74 74
75#define INT_MAX 0x7fffffff75#if defined(JAS_HAVE_SYS_TYPES_H)
76#define UINT_FAST32_MAX 0xffffffff76#include <sys/types.h> /* IWYU pragma: export */
77#define SIZE_MAX UINT_FAST32_MAX77#endif
78#define INT_FAST32_MIN ((s32int)0x80000000)78
79#define INT_FAST32_MAX INT_MAX79#ifdef __cplusplus
80#define LONG_MAX INT_MAX80extern "C" {
81 81#endif
82typedef s8int int_least8_t;82
83typedef s16int int_fast16_t;83#define jas_uchar unsigned char
84typedef s32int int_fast32_t;84#define jas_uint unsigned int
85typedef s32int int_least32_t;85#define jas_ulong unsigned long
86typedef s64int int_fast64_t;86#define jas_longlong long long
87 87#define jas_ulonglong unsigned long long
88typedef u8int uint_least8_t;88
89typedef u8int uint_fast8_t;89#if !defined(JAS_NO_SET_SSIZE_T)
90typedef u16int uint_fast16_t;90# if !defined(SSIZE_MAX)
91typedef u16int uint_least16_t;91# if (JAS_SIZEOF_INT == JAS_SIZEOF_SIZE_T)
92typedef u32int uint_fast32_t;92# define ssize_t int
93typedef u32int uint_least32_t;93# define SSIZE_MAX INT_MAX
94typedef u64int uint_least64_t;94# elif (JAS_SIZEOF_LONG == JAS_SIZEOF_SIZE_T)
95typedef u64int uint_fast64_t;95# define ssize_t long
96 96# define SSIZE_MAX LONG_MAX
97typedef unsigned char jas_uchar;97# else
98typedef unsigned int jas_uint;98# define ssize_t jas_longlong
99typedef unsigned long jas_ulong;99# define SSIZE_MAX LLONG_MAX
100typedef long long jas_longlong;100# endif
101typedef unsigned long long jas_ulonglong;101# endif
102 102#endif
103typedef enum { false, true } bool;103
104#if 0
105#if defined(JAS_HAVE_SSIZE_T)
106#define jas_ssize_t ssize_t
107#define JAS_SSIZE_MAX SSIZE_MAX
108#else
109#define jas_ssize_t jas_longlong
110#define JAS_SSIZE_MAX LLONG_MAX
111#endif
112#endif
113
114#if defined(_MSC_VER) && (_MSC_VER < 1800)
115#define bool int
116#define false 0
117#define true 1
104 118
105#define PRIxFAST32 "x"119#define PRIxFAST32 "x"
106#define PRIxFAST16 PRIxFAST32120#define PRIxFAST16 PRIxFAST32
107#define PRIuFAST32 "u"121#define PRIuFAST32 "u"
108#define PRIuFAST16 PRIuFAST32122#define PRIuFAST16 PRIuFAST32
109#define PRIiFAST32 "i"123#define PRIiFAST32 "i"
110#define PRIiLEAST32 PRIiFAST32124#ifdef _WIN64
111#define PRIxLEAST16 "x"125 #define PRIdPTR "lld"
112#define PRIdPTR "lld"126#else
113#define _HUGE_ENUF 1e+300127 #define PRIdPTR "d"
128#endif
129
130#ifndef _HUGE_ENUF
131 #define _HUGE_ENUF 1e+300
132#endif
133
114#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF))134#define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF))
115 135
136#define strtoull _strtoui64
137
138#endif
139
116/* The below macro is intended to be used for type casts. By using this140/* The below macro is intended to be used for type casts. By using this
117 macro, type casts can be easily located in the source code with141 macro, type casts can be easily located in the source code with
118 tools like "grep". */142 tools like "grep". */
@@ -123,10 +147,60 @@ typedef enum { false, true } bool; · 4 unmodified lines
123/* NOTE: This could underestimate the size on some exotic architectures. */147/* NOTE: This could underestimate the size on some exotic architectures. */
124#define JAS_UINTFAST32_NUMBITS (8 * sizeof(uint_fast32_t))148#define JAS_UINTFAST32_NUMBITS (8 * sizeof(uint_fast32_t))
125 149
126#ifdef __cplusplus150#if 0
127extern "C" {151#if defined(JAS_HAVE_MAX_ALIGN_T)
152#define jas_max_align_t max_align_t
153#else
154#define jas_max_align_t long double
155#endif
156#endif
157
158/*
159Assume that a compiler claiming to be compliant with C11 or a later version
160of the C standard provides a suitable definition of max_align_t.
161The JAS_NO_SET_MAX_ALIGN_T preprocessor symbol can be used to override
162this behavior.
163*/
164#if defined(JAS_NO_SET_MAX_ALIGN_T)
165 /*
166 The user of this header is assuming responsibility for providing a
167 suitable definition for max_align_t.
168 */
169#elif defined(_MSC_VER)
170 /*
171 Define max_align_t as a preprocessor symbol since using typedef will
172 cause problems.
173 */
174# define max_align_t long double
175#elif !(defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 201112L))
176# define max_align_t long double
128#endif177#endif
129 178
179#if 0
180#if defined(JAS_HAVE_UINTMAX_T)
181#define jas_uintmax_t uintmax_t
182#else
183#define jas_uintmax_t uint_fast64_t
184#endif
185#endif
186
187#if 0
188#if defined(JAS_HAVE_INTMAX_T)
189#define jas_intmax_t intmax_t
190#else
191#define jas_intmax_t int_fast64_t
192#endif
193#endif
194
195/* 32-bit unsigned integer type */
196typedef uint_least32_t jas_ui32_t;
197#define JAS_UI32_MAX UINT_LEAST32_MAX
198
199/* 32-bit signed integer type */
200typedef int_least32_t jas_i32_t;
201#define JAS_I32_MIN INT_LEAST32_MIN
202#define JAS_I32_MAX INT_LEAST32_MAX
203
130#ifdef __cplusplus204#ifdef __cplusplus
131}205}
132#endif206#endif
jasper/jas_version.h+113−0
@@ -0,0 +1,113 @@
1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2003 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64/*!
65 * @file jas_version.h
66 * @brief JasPer Version
67 */
68
69#ifndef JAS_VERSION_H
70#define JAS_VERSION_H
71
72/* The configuration header file should be included first. */
73#include <jasper/jas_config.h>
74
75#ifdef __cplusplus
76extern "C" {
77#endif
78
79/******************************************************************************\
80* Constants and types.
81\******************************************************************************/
82
83#define JAS_COPYRIGHT \
84 "Copyright (c) 2001-2022 Michael David Adams.\n" \
85 "Copyright (c) 1999-2000 Image Power, Inc. and the University of\n" \
86 " British Columbia.\n" \
87 "All rights reserved.\n"
88
89#define JAS_NOTES \
90 "For information about the JasPer project, see:\n" \
91 " https://jasper-software.github.io/jasper\n" \
92 " https://www.ece.uvic.ca/~mdadams/jasper\n" \
93 "For online documentation on the JasPer software, see:\n" \
94 " https://jasper-software.github.io/jasper-manual\n" \
95 "Please submit bug reports using the bug-tracker at:\n" \
96 " https://github.com/jasper-software/jasper/issues\n"
97
98/******************************************************************************\
99* Functions.
100\******************************************************************************/
101
102JAS_ATTRIBUTE_CONST
103JAS_EXPORT
104const char *jas_getversion(void);
105/* Get the version information for the JasPer library. */
106/* Note: Since libjasper can be built as a shared library, the version
107 returned by this function may not necessarily correspond to JAS_VERSION. */
108
109#ifdef __cplusplus
110}
111#endif
112
113#endif
jasper/jasper.h+6−0
@@ -73,6 +73,7 @@ · 72 unmodified lines
73#include <jasper/jas_config.h>73#include <jasper/jas_config.h>
74 74
75#include <jasper/jas_types.h>75#include <jasper/jas_types.h>
76#include <jasper/jas_version.h>
76 77
77#include <jasper/jas_init.h>78#include <jasper/jas_init.h>
78#include <jasper/jas_cm.h>79#include <jasper/jas_cm.h>
@@ -84,6 +85,11 @@ · 5 unmodified lines
84#include <jasper/jas_malloc.h>85#include <jasper/jas_malloc.h>
85#include <jasper/jas_seq.h>86#include <jasper/jas_seq.h>
86#include <jasper/jas_stream.h>87#include <jasper/jas_stream.h>
88#include <jasper/jas_string.h>
89#include <jasper/jas_tvp.h>
90#include <jasper/jas_thread.h>
91#include <jasper/jas_init.h>
92#include <jasper/jas_log.h>
87 93
88#pragma lib "./libjp2.a"94#pragma lib "./libjp2.a"
89 95
jp2.c+4−1
@@ -34,7 +34,10 @@ main(int argc, char **argv) · 33 unmodified lines
34 usage();34 usage();
35 35
36 memimageinit();36 memimageinit();
37 jas_init();37 jas_conf_clear();
38 jas_conf_set_max_mem_usage(512*1024*1024);
39 jas_init_library();
40 jas_init_thread();
38 41
39 if((cp = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB)) == nil){42 if((cp = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB)) == nil){
40 werrstr("failed to create color space");43 werrstr("failed to create color space");
jp2_cod.c+160−50
@@ -75,13 +75,12 @@ · 74 unmodified lines
75 75
76#include "jasper/jas_malloc.h"76#include "jasper/jas_malloc.h"
77#include "jasper/jas_debug.h"77#include "jasper/jas_debug.h"
78#include "jasper/jas_types.h"
78 79
79/******************************************************************************\80/******************************************************************************\
80* Function prototypes.81* Function prototypes.
81\******************************************************************************/82\******************************************************************************/
82 83
83#define ONES(n) ((1 << (n)) - 1)
84
85static const jp2_boxinfo_t *jp2_boxinfolookup(int type);84static const jp2_boxinfo_t *jp2_boxinfolookup(int type);
86 85
87static int jp2_getuint8(jas_stream_t *in, uint_fast8_t *val);86static int jp2_getuint8(jas_stream_t *in, uint_fast8_t *val);
@@ -95,6 +94,8 @@ static int jp2_putuint64(jas_stream_t *out, uint_fast64_t val); · 7 unmodified lines
95 94
96static int jp2_getint(jas_stream_t *in, int s, int n, int_fast32_t *val);95static int jp2_getint(jas_stream_t *in, int s, int n, int_fast32_t *val);
97 96
97static void jp2_box_dump(const jp2_box_t *box);
98
98static int jp2_jp_getdata(jp2_box_t *box, jas_stream_t *in);99static int jp2_jp_getdata(jp2_box_t *box, jas_stream_t *in);
99static int jp2_jp_putdata(const jp2_box_t *box, jas_stream_t *out);100static int jp2_jp_putdata(const jp2_box_t *box, jas_stream_t *out);
100static int jp2_ftyp_getdata(jp2_box_t *box, jas_stream_t *in);101static int jp2_ftyp_getdata(jp2_box_t *box, jas_stream_t *in);
@@ -106,46 +107,78 @@ static int jp2_bpcc_getdata(jp2_box_t *box, jas_stream_t *in); · 5 unmodified lines
106static int jp2_bpcc_putdata(const jp2_box_t *box, jas_stream_t *out);107static int jp2_bpcc_putdata(const jp2_box_t *box, jas_stream_t *out);
107static int jp2_colr_getdata(jp2_box_t *box, jas_stream_t *in);108static int jp2_colr_getdata(jp2_box_t *box, jas_stream_t *in);
108static int jp2_colr_putdata(const jp2_box_t *box, jas_stream_t *out);109static int jp2_colr_putdata(const jp2_box_t *box, jas_stream_t *out);
110static void jp2_colr_dumpdata(const jp2_box_t *box);
109static void jp2_colr_destroy(jp2_box_t *box);111static void jp2_colr_destroy(jp2_box_t *box);
110static void jp2_cdef_destroy(jp2_box_t *box);112static void jp2_cdef_destroy(jp2_box_t *box);
111static int jp2_cdef_getdata(jp2_box_t *box, jas_stream_t *in);113static int jp2_cdef_getdata(jp2_box_t *box, jas_stream_t *in);
112static int jp2_cdef_putdata(const jp2_box_t *box, jas_stream_t *out);114static int jp2_cdef_putdata(const jp2_box_t *box, jas_stream_t *out);
115static void jp2_cdef_dumpdata(const jp2_box_t *box);
113static void jp2_cmap_destroy(jp2_box_t *box);116static void jp2_cmap_destroy(jp2_box_t *box);
114static int jp2_cmap_getdata(jp2_box_t *box, jas_stream_t *in);117static int jp2_cmap_getdata(jp2_box_t *box, jas_stream_t *in);
115static int jp2_cmap_putdata(const jp2_box_t *box, jas_stream_t *out);118static int jp2_cmap_putdata(const jp2_box_t *box, jas_stream_t *out);
119static void jp2_cmap_dumpdata(const jp2_box_t *box);
116static void jp2_pclr_destroy(jp2_box_t *box);120static void jp2_pclr_destroy(jp2_box_t *box);
117static int jp2_pclr_getdata(jp2_box_t *box, jas_stream_t *in);121static int jp2_pclr_getdata(jp2_box_t *box, jas_stream_t *in);
118static int jp2_pclr_putdata(const jp2_box_t *box, jas_stream_t *out);122static int jp2_pclr_putdata(const jp2_box_t *box, jas_stream_t *out);
123static void jp2_pclr_dumpdata(const jp2_box_t *box);
124
125/******************************************************************************\
126\******************************************************************************/
127
128static inline uint_fast32_t ones(int n)
129{
130 assert(n >= 0);
131 return (JAS_CAST(uint_fast32_t, 1) << n) - 1;
132}
119 133
120/******************************************************************************\134/******************************************************************************\
121* Local data.135* Local data.
122\******************************************************************************/136\******************************************************************************/
123 137
124static const jp2_boxinfo_t jp2_boxinfos[] = {138static const jp2_boxinfo_t jp2_boxinfos[] = {
125 {JP2_BOX_JP, 0, "JP", {0, 0, jp2_jp_getdata, jp2_jp_putdata}},139 {JP2_BOX_JP, 0, "JP",
126 {JP2_BOX_FTYP, 0, "FTYP", {0, 0, jp2_ftyp_getdata, jp2_ftyp_putdata}},140 {0, 0, jp2_jp_getdata, jp2_jp_putdata, 0}},
127 {JP2_BOX_JP2H, JP2_BOX_SUPER, "JP2H", {0, 0, 0, 0}},141 {JP2_BOX_FTYP, 0, "FTYP",
128 {JP2_BOX_IHDR, 0, "IHDR", {0, 0, jp2_ihdr_getdata, jp2_ihdr_putdata}},142 {0, 0, jp2_ftyp_getdata, jp2_ftyp_putdata, 0}},
129 {JP2_BOX_BPCC, 0, "BPCC", {0, jp2_bpcc_destroy, jp2_bpcc_getdata, jp2_bpcc_putdata}},143 {JP2_BOX_JP2H, JP2_BOX_SUPER, "JP2H",
130 {JP2_BOX_COLR, 0, "COLR", {0, jp2_colr_destroy, jp2_colr_getdata, jp2_colr_putdata}},144 {0, 0, 0, 0, 0}},
131 {JP2_BOX_PCLR, 0, "PCLR", {0, jp2_pclr_destroy, jp2_pclr_getdata, jp2_pclr_putdata}},145 {JP2_BOX_IHDR, 0, "IHDR",
132 {JP2_BOX_CMAP, 0, "CMAP", {0, jp2_cmap_destroy, jp2_cmap_getdata, jp2_cmap_putdata}},146 {0, 0, jp2_ihdr_getdata, jp2_ihdr_putdata, 0}},
133 {JP2_BOX_CDEF, 0, "CDEF", {0, jp2_cdef_destroy, jp2_cdef_getdata, jp2_cdef_putdata}},147 {JP2_BOX_BPCC, 0, "BPCC",
134 {JP2_BOX_RES, JP2_BOX_SUPER, "RES", {0, 0, 0, 0}},148 {0, jp2_bpcc_destroy, jp2_bpcc_getdata, jp2_bpcc_putdata, 0}},
135 {JP2_BOX_RESC, 0, "RESC", {0, 0, 0, 0}},149 {JP2_BOX_COLR, 0, "COLR",
136 {JP2_BOX_RESD, 0, "RESD", {0, 0, 0, 0}},150 {0, jp2_colr_destroy, jp2_colr_getdata, jp2_colr_putdata, jp2_colr_dumpdata}},
137 {JP2_BOX_JP2C, JP2_BOX_NODATA, "JP2C", {0, 0, 0, 0}},151 {JP2_BOX_PCLR, 0, "PCLR",
138 {JP2_BOX_JP2I, 0, "JP2I", {0, 0, 0, 0}},152 {0, jp2_pclr_destroy, jp2_pclr_getdata, jp2_pclr_putdata, jp2_pclr_dumpdata}},
139 {JP2_BOX_XML, 0, "XML", {0, 0, 0, 0}},153 {JP2_BOX_CMAP, 0, "CMAP",
140 {JP2_BOX_UUID, 0, "UUID", {0, 0, 0, 0}},154 {0, jp2_cmap_destroy, jp2_cmap_getdata, jp2_cmap_putdata, jp2_cmap_dumpdata}},
141 {JP2_BOX_UINF, JP2_BOX_SUPER, "UINF", {0, 0, 0, 0}},155 {JP2_BOX_CDEF, 0, "CDEF",
142 {JP2_BOX_ULST, 0, "ULST", {0, 0, 0, 0}},156 {0, jp2_cdef_destroy, jp2_cdef_getdata, jp2_cdef_putdata, jp2_cdef_dumpdata}},
143 {JP2_BOX_URL, 0, "URL", {0, 0, 0, 0}},157 {JP2_BOX_RES, JP2_BOX_SUPER, "RES",
144 {0, 0, 0, {0, 0, 0, 0}},158 {0, 0, 0, 0, 0}},
159 {JP2_BOX_RESC, 0, "RESC",
160 {0, 0, 0, 0, 0}},
161 {JP2_BOX_RESD, 0, "RESD",
162 {0, 0, 0, 0, 0}},
163 {JP2_BOX_JP2C, JP2_BOX_NODATA, "JP2C",
164 {0, 0, 0, 0, 0}},
165 {JP2_BOX_JP2I, 0, "JP2I",
166 {0, 0, 0, 0, 0}},
167 {JP2_BOX_XML, 0, "XML",
168 {0, 0, 0, 0, 0}},
169 {JP2_BOX_UUID, 0, "UUID",
170 {0, 0, 0, 0, 0}},
171 {JP2_BOX_UINF, JP2_BOX_SUPER, "UINF",
172 {0, 0, 0, 0, 0}},
173 {JP2_BOX_ULST, 0, "ULST",
174 {0, 0, 0, 0, 0}},
175 {JP2_BOX_URL, 0, "URL",
176 {0, 0, 0, 0, 0}},
177 {0, 0, 0, {0, 0, 0, 0, 0}},
145};178};
146 179
147static const jp2_boxinfo_t jp2_boxinfo_unk = {180static const jp2_boxinfo_t jp2_boxinfo_unk = {
148 0, 0, "Unknown", {0, 0, 0, 0}181 0, 0, "Unknown", {0, 0, 0, 0, 0}
149};182};
150 183
151/******************************************************************************\184/******************************************************************************\
@@ -239,19 +272,19 @@ jp2_box_t *jp2_box_get(jas_stream_t *in) · 87 unmodified lines
239 boxinfo = jp2_boxinfolookup(box->type);272 boxinfo = jp2_boxinfolookup(box->type);
240 box->info = boxinfo;273 box->info = boxinfo;
241 box->len = len;274 box->len = len;
242 JAS_DBGLOG(10, (275 JAS_LOGDEBUGF(10,
243 "preliminary processing of JP2 box: "276 "preliminary processing of JP2 box: "
244 "type=%c%s%c (0x%08x); length=%"PRIuFAST32"\n",277 "type=%c%s%c (0x%08x); length=%"PRIuFAST32"\n",
245 '"', boxinfo->name, '"', box->type, box->len278 '"', boxinfo->name, '"', box->type, box->len
246 ));279 );
247 size_t hdrlen;280 size_t hdrlen;
248 if (box->len == 1) {281 if (box->len == 1) {
249 JAS_DBGLOG(10, ("big length\n"));282 JAS_LOGDEBUGF(10, "big length\n");
250 if (jp2_getuint64(in, &extlen)) {283 if (jp2_getuint64(in, &extlen)) {
251 goto error;284 goto error;
252 }285 }
253 if (extlen > 0xffffffffUL) {286 if (extlen > 0xffffffffUL) {
254 jas_eprintf("warning: cannot handle large 64-bit box length\n");287 jas_logerrorf("cannot handle large 64-bit box length\n");
255 goto error;288 goto error;
256 }289 }
257 box->len = extlen;290 box->len = extlen;
@@ -262,10 +295,9 @@ jp2_box_t *jp2_box_get(jas_stream_t *in) · 4 unmodified lines
262 if (box->len != 0 && box->len < 8) {295 if (box->len != 0 && box->len < 8) {
263 goto error;296 goto error;
264 }297 }
265 if (box->len > 0x7fffffffUL) {298 if (box->len > SSIZE_MAX) {
266 /* this limit is the largest value which can299 /* This limit is the largest value which can be passed to
267 be passed to jas_stream_copy() without300 jas_stream_copy() without overflowing. */
268 overflowing */
269 goto error;301 goto error;
270 }302 }
271 303
@@ -280,7 +312,7 @@ jp2_box_t *jp2_box_get(jas_stream_t *in) · 8 unmodified lines
280 goto error;312 goto error;
281 }313 }
282 if (jas_stream_copy(tmpstream, in, box->datalen)) {314 if (jas_stream_copy(tmpstream, in, box->datalen)) {
283 jas_eprintf("cannot copy box data\n");315 jas_logerrorf("cannot copy box data\n");
284 goto error;316 goto error;
285 }317 }
286 jas_stream_rewind(tmpstream);318 jas_stream_rewind(tmpstream);
@@ -291,13 +323,17 @@ jp2_box_t *jp2_box_get(jas_stream_t *in) · 4 unmodified lines
291 323
292 if (box->ops->getdata) {324 if (box->ops->getdata) {
293 if ((*box->ops->getdata)(box, tmpstream)) {325 if ((*box->ops->getdata)(box, tmpstream)) {
294 jas_eprintf("cannot parse box data\n");326 jas_logerrorf("cannot parse box data\n");
295 goto error;327 goto error;
296 }328 }
297 }329 }
298 jas_stream_close(tmpstream);330 jas_stream_close(tmpstream);
299 }331 }
300 332
333 if (jas_get_debug_level() >= 1) {
334 jp2_box_dump(box);
335 }
336
301 return box;337 return box;
302 338
303error:339error:
@@ -310,6 +346,19 @@ error: · 6 unmodified lines
310 return 0;346 return 0;
311}347}
312 348
349static void jp2_box_dump(const jp2_box_t *box)
350{
351 const jp2_boxinfo_t *boxinfo = box->info;
352 assert(boxinfo);
353
354 jas_logprintf(
355 "JP2 box: type=%c%s%c (0x%08"PRIxFAST32"); length=%"PRIuFAST32"\n", '"',
356 boxinfo->name, '"', box->type, box->len);
357 if (box->ops->dumpdata) {
358 (*box->ops->dumpdata)(box);
359 }
360}
361
313static int jp2_jp_getdata(jp2_box_t *box, jas_stream_t *in)362static int jp2_jp_getdata(jp2_box_t *box, jas_stream_t *in)
314{363{
315 jp2_jp_t *jp = &box->data.jp;364 jp2_jp_t *jp = &box->data.jp;
@@ -376,6 +425,20 @@ static int jp2_bpcc_getdata(jp2_box_t *box, jas_stream_t *in) · 60 unmodified lines
376 return 0;425 return 0;
377}426}
378 427
428static void jp2_colr_dumpdata(const jp2_box_t *box)
429{
430 const jp2_colr_t *colr = &box->data.colr;
431 jas_logprintf("method=%d; pri=%d; approx=%d\n", (int)colr->method, (int)colr->pri, (int)colr->approx);
432 switch (colr->method) {
433 case JP2_COLR_ENUM:
434 jas_logprintf("csid=%d\n", (int)colr->csid);
435 break;
436 case JP2_COLR_ICC:
437 jas_logmemdump(colr->iccp, colr->iccplen);
438 break;
439 }
440}
441
379static int jp2_colr_getdata(jp2_box_t *box, jas_stream_t *in)442static int jp2_colr_getdata(jp2_box_t *box, jas_stream_t *in)
380{443{
381 if (box->datalen < 3)444 if (box->datalen < 3)
@@ -388,23 +451,33 @@ static int jp2_colr_getdata(jp2_box_t *box, jas_stream_t *in) · 6 unmodified lines
388 451
389 if (jp2_getuint8(in, &colr->method) || jp2_getuint8(in, &colr->pri) ||452 if (jp2_getuint8(in, &colr->method) || jp2_getuint8(in, &colr->pri) ||
390 jp2_getuint8(in, &colr->approx)) {453 jp2_getuint8(in, &colr->approx)) {
454 jas_logerrorf("cannot get COLR box data\n");
391 return -1;455 return -1;
392 }456 }
393 switch (colr->method) {457 switch (colr->method) {
394 case JP2_COLR_ENUM:458 case JP2_COLR_ENUM:
395 if (jp2_getuint32(in, &colr->csid)) {459 if (jp2_getuint32(in, &colr->csid)) {
460 jas_logerrorf("cannot get CSID\n");
396 return -1;461 return -1;
397 }462 }
398 break;463 break;
399 case JP2_COLR_ICC:464 case JP2_COLR_ICC:
465 if (box->datalen <= 3) {
466 jas_logerrorf("empty ICC profile data\n");
467 return -1;
468 }
469 assert(box->datalen >= 3);
400 colr->iccplen = box->datalen - 3;470 colr->iccplen = box->datalen - 3;
401 if (colr->iccplen > 1024 * 1024)471#if 0
472 if (colr->iccplen > 1024 * 1024) {
402 /* refuse to read ICC profiles larger than 1473 /* refuse to read ICC profiles larger than 1
403 MB (I have no idea how large ICC profiles474 MB (I have no idea how large ICC profiles
404 can get, but I believe this limit might be475 can get, but I believe this limit might be
405 very pessimistic and should be lowered476 very pessimistic and should be lowered
406 further) */477 further) */
407 return -1;478 return -1;
479 }
480#endif
408 if (!(colr->iccp = jas_alloc2(colr->iccplen, sizeof(uint_fast8_t)))) {481 if (!(colr->iccp = jas_alloc2(colr->iccplen, sizeof(uint_fast8_t)))) {
409 return -1;482 return -1;
410 }483 }
@@ -416,6 +489,17 @@ static int jp2_colr_getdata(jp2_box_t *box, jas_stream_t *in) · 5 unmodified lines
416 return 0;489 return 0;
417}490}
418 491
492static void jp2_cdef_dumpdata(const jp2_box_t *box)
493{
494 const jp2_cdef_t *cdef = &box->data.cdef;
495 unsigned int i;
496 for (i = 0; i < cdef->numchans; ++i) {
497 jas_logprintf(
498 "channo=%"PRIuFAST16"; type=%"PRIuFAST16"; assoc=%"PRIuFAST16"\n",
499 cdef->ents[i].channo, cdef->ents[i].type, cdef->ents[i].assoc);
500 }
501}
502
419static void jp2_colr_destroy(jp2_box_t *box)503static void jp2_colr_destroy(jp2_box_t *box)
420{504{
421 jp2_colr_t *colr = &box->data.colr;505 jp2_colr_t *colr = &box->data.colr;
@@ -472,7 +556,7 @@ int jp2_box_put(jp2_box_t *box, jas_stream_t *out) · 50 unmodified lines
472 box->len = jas_stream_tell(tmpstream) + JP2_BOX_HDRLEN(false);556 box->len = jas_stream_tell(tmpstream) + JP2_BOX_HDRLEN(false);
473 jas_stream_rewind(tmpstream);557 jas_stream_rewind(tmpstream);
474 }558 }
475 extlen = (box->len >= (((uint_fast64_t)1) << 32)) != 0;559 extlen = 0;
476 if (jp2_putuint32(out, extlen ? 1 : box->len)) {560 if (jp2_putuint32(out, extlen ? 1 : box->len)) {
477 goto error;561 goto error;
478 }562 }
@@ -488,7 +572,7 @@ int jp2_box_put(jp2_box_t *box, jas_stream_t *out) · 9 unmodified lines
488 if (dataflag) {572 if (dataflag) {
489 if (jas_stream_copy(out, tmpstream, box->len -573 if (jas_stream_copy(out, tmpstream, box->len -
490 JP2_BOX_HDRLEN(false))) {574 JP2_BOX_HDRLEN(false))) {
491 jas_eprintf("cannot copy box data\n");575 jas_logerrorf("cannot copy box data\n");
492 goto error;576 goto error;
493 }577 }
494 jas_stream_close(tmpstream);578 jas_stream_close(tmpstream);
@@ -703,10 +787,6 @@ static const jp2_boxinfo_t *jp2_boxinfolookup(int type) · 208 unmodified lines
703 return &jp2_boxinfo_unk;787 return &jp2_boxinfo_unk;
704}788}
705 789
706
707
708
709
710static void jp2_cmap_destroy(jp2_box_t *box)790static void jp2_cmap_destroy(jp2_box_t *box)
711{791{
712 jp2_cmap_t *cmap = &box->data.cmap;792 jp2_cmap_t *cmap = &box->data.cmap;
@@ -746,13 +826,23 @@ static int jp2_cmap_getdata(jp2_box_t *box, jas_stream_t *in) · 33 unmodified lines
746 826
747static int jp2_cmap_putdata(const jp2_box_t *box, jas_stream_t *out)827static int jp2_cmap_putdata(const jp2_box_t *box, jas_stream_t *out)
748{828{
749 /* Eliminate compiler warning about unused variables. */829 JAS_UNUSED(box);
750 USED(box);830 JAS_UNUSED(out);
751 USED(out);
752
753 return -1;831 return -1;
754}832}
755 833
834static void jp2_cmap_dumpdata(const jp2_box_t *box)
835{
836 const jp2_cmap_t *cmap = &box->data.cmap;
837 unsigned int i;
838 jas_logprintf("numchans = %d\n", (int) cmap->numchans);
839 for (i = 0; i < cmap->numchans; ++i) {
840 const jp2_cmapent_t *ent = &cmap->ents[i];
841 jas_logprintf("cmptno=%d; map=%d; pcol=%d\n",
842 (int) ent->cmptno, (int) ent->map, (int) ent->pcol);
843 }
844}
845
756static void jp2_pclr_destroy(jp2_box_t *box)846static void jp2_pclr_destroy(jp2_box_t *box)
757{847{
758 jp2_pclr_t *pclr = &box->data.pclr;848 jp2_pclr_t *pclr = &box->data.pclr;
@@ -813,12 +903,26 @@ static int jp2_pclr_putdata(const jp2_box_t *box, jas_stream_t *out) · 54 unmodified lines
813#if 0903#if 0
814 const jp2_pclr_t *pclr = &box->data.pclr;904 const jp2_pclr_t *pclr = &box->data.pclr;
815#endif905#endif
816 /* Eliminate warning about unused variable. */906 JAS_UNUSED(box);
817 USED(box);907 JAS_UNUSED(out);
818 USED(out);
819 return -1;908 return -1;
820}909}
821 910
911static void jp2_pclr_dumpdata(const jp2_box_t *box)
912{
913 const jp2_pclr_t *pclr = &box->data.pclr;
914 unsigned int i;
915 int j;
916 jas_logprintf("numents=%d; numchans=%d\n", (int) pclr->numlutents,
917 (int) pclr->numchans);
918 for (i = 0; i < pclr->numlutents; ++i) {
919 for (j = 0; j < pclr->numchans; ++j) {
920 jas_logprintf("LUT[%d][%d]=%"PRIiFAST32"\n", i, j,
921 pclr->lutdata[i * pclr->numchans + j]);
922 }
923 }
924}
925
822static int jp2_getint(jas_stream_t *in, int s, int n, int_fast32_t *val)926static int jp2_getint(jas_stream_t *in, int s, int n, int_fast32_t *val)
823{927{
824 int c;928 int c;
@@ -828,6 +932,12 @@ static int jp2_getint(jas_stream_t *in, int s, int n, int_fast32_t *val) · 3 unmodified lines
828 932
829 m = (n + 7) / 8;933 m = (n + 7) / 8;
830 934
935 // Ensure that the integer to be read has a valid size.
936 if (n < 0 || n > 32) {
937 jas_logerrorf("jp2_getint: invalid integer size (%d bits)\n", n);
938 return -1;
939 }
940
831 v = 0;941 v = 0;
832 for (i = 0; i < m; ++i) {942 for (i = 0; i < m; ++i) {
833 if ((c = jas_stream_getc(in)) == EOF) {943 if ((c = jas_stream_getc(in)) == EOF) {
@@ -835,11 +945,11 @@ static int jp2_getint(jas_stream_t *in, int s, int n, int_fast32_t *val) · 1 unmodified line
835 }945 }
836 v = (v << 8) | c;946 v = (v << 8) | c;
837 }947 }
838 v &= ONES(n);948 v &= ones(n);
839 if (s) {949 if (s) {
840 int sb;950 int sb;
841 sb = v & (1 << (8 * m - 1));951 sb = v & (JAS_CAST(uint_fast32_t, 1) << (8 * m - 1));
842 *val = ((~v) + 1) & ONES(8 * m);952 *val = ((~v) + 1) & ones(8 * m);
843 if (sb) {953 if (sb) {
844 *val = -*val;954 *val = -*val;
845 }955 }
jp2_cod.h+2−2
@@ -245,7 +245,7 @@ typedef struct { · 244 unmodified lines
245 uint_fast32_t type;245 uint_fast32_t type;
246 246
247 /* The length of the box including the (variable-length) header. */247 /* The length of the box including the (variable-length) header. */
248 uint_fast64_t len;248 uint_fast32_t len;
249 249
250 /* The length of the box data. */250 /* The length of the box data. */
251 uint_fast32_t datalen;251 uint_fast32_t datalen;
@@ -268,6 +268,7 @@ typedef struct jp2_boxops_s { · 16 unmodified lines
268 void (*destroy)(jp2_box_t *box);268 void (*destroy)(jp2_box_t *box);
269 int (*getdata)(jp2_box_t *box, jas_stream_t *in);269 int (*getdata)(jp2_box_t *box, jas_stream_t *in);
270 int (*putdata)(const jp2_box_t *box, jas_stream_t *out);270 int (*putdata)(const jp2_box_t *box, jas_stream_t *out);
271 void (*dumpdata)(const jp2_box_t *box);
271} jp2_boxops_t;272} jp2_boxops_t;
272 273
273/******************************************************************************\274/******************************************************************************\
@@ -308,5 +309,4 @@ static inline uint_least8_t JP2_BPCTODTYPE(uint_least8_t bpc) · 34 unmodified lines
308 309
309const jp2_cdefchan_t *jp2_cdef_lookup(jp2_cdef_t *cdef, int channo);310const jp2_cdefchan_t *jp2_cdef_lookup(jp2_cdef_t *cdef, int channo);
310 311
311
312#endif312#endif
jp2_dec.c+113−59
@@ -81,7 +81,9 @@ · 80 unmodified lines
81#include "jasper/jas_malloc.h"81#include "jasper/jas_malloc.h"
82#include "jasper/jas_types.h"82#include "jasper/jas_types.h"
83 83
84#define JP2_VALIDATELEN (JAS_MIN(JP2_JP_LEN + 16, JAS_STREAM_MAXPUTBACK))84/******************************************************************************\
85* Function prototypes.
86\******************************************************************************/
85 87
86static jp2_dec_t *jp2_dec_create(void);88static jp2_dec_t *jp2_dec_create(void);
87static void jp2_dec_destroy(jp2_dec_t *dec);89static void jp2_dec_destroy(jp2_dec_t *dec);
@@ -104,7 +106,10 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 16 unmodified lines
104 unsigned int i;106 unsigned int i;
105 jp2_cmap_t *cmapd;107 jp2_cmap_t *cmapd;
106 jp2_pclr_t *pclrd;108 jp2_pclr_t *pclrd;
109#if 0
110 /* The following code appears to no longer be needed. */
107 jp2_cdef_t *cdefd;111 jp2_cdef_t *cdefd;
112#endif
108 unsigned int channo;113 unsigned int channo;
109 int newcmptno;114 int newcmptno;
110 int_fast32_t *lutents;115 int_fast32_t *lutents;
@@ -117,8 +122,9 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 6 unmodified lines
117 jas_iccprof_t *iccprof;122 jas_iccprof_t *iccprof;
118 123
119 box = 0;124 box = 0;
125 image = 0;
120 126
121 JAS_DBGLOG(100, ("jp2_decode(%p, \"%s\")\n", in, optstr));127 JAS_LOGDEBUGF(100, "jp2_decode(%p, \"%s\")\n", in, optstr);
122 128
123 if (!(dec = jp2_dec_create())) {129 if (!(dec = jp2_dec_create())) {
124 goto error;130 goto error;
@@ -126,25 +132,28 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 1 unmodified line
126 132
127 /* Get the first box. This should be a JP box. */133 /* Get the first box. This should be a JP box. */
128 if (!(box = jp2_box_get(in))) {134 if (!(box = jp2_box_get(in))) {
129 jas_eprintf("error: cannot get box\n");135 jas_logerrorf("error: cannot get box\n");
130 goto error;136 goto error;
131 }137 }
132 if (box->type != JP2_BOX_JP) {138 if (box->type != JP2_BOX_JP) {
133 jas_eprintf("error: expecting signature box\n");139 jas_logerrorf("error: expecting signature box\n");
134 goto error;140 goto error;
135 }141 }
136 if (box->data.jp.magic != JP2_JP_MAGIC) {142 if (box->data.jp.magic != JP2_JP_MAGIC) {
137 jas_eprintf("incorrect magic number\n");143 jas_logerrorf("incorrect magic number (0x%lx != 0x%lx)\n",
144 JAS_CAST(unsigned long, box->data.jp.magic),
145 JAS_CAST(unsigned long, JP2_JP_MAGIC));
138 goto error;146 goto error;
139 }147 }
140 jp2_box_destroy(box);148 jp2_box_destroy(box);
141 149
142 /* Get the second box. This should be a FTYP box. */150 /* Get the second box. This should be a FTYP box. */
143 if (!(box = jp2_box_get(in))) {151 if (!(box = jp2_box_get(in))) {
152 jas_logerrorf("error: cannot get box\n");
144 goto error;153 goto error;
145 }154 }
146 if (box->type != JP2_BOX_FTYP) {155 if (box->type != JP2_BOX_FTYP) {
147 jas_eprintf("expecting file type box\n");156 jas_logerrorf("expecting file type box\n");
148 goto error;157 goto error;
149 }158 }
150 jp2_box_destroy(box);159 jp2_box_destroy(box);
@@ -152,8 +161,8 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 1 unmodified line
152 /* Get more boxes... */161 /* Get more boxes... */
153 found = 0;162 found = 0;
154 while ((box = jp2_box_get(in))) {163 while ((box = jp2_box_get(in))) {
155 if (jas_getdbglevel() >= 1) {164 if (jas_get_debug_level() >= 1) {
156 jas_eprintf("got box type %s\n", box->info->name);165 jas_logdebugf(1, "got box type %s\n", box->info->name);
157 }166 }
158 switch (box->type) {167 switch (box->type) {
159 case JP2_BOX_JP2C:168 case JP2_BOX_JP2C:
@@ -206,18 +215,18 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 46 unmodified lines
206 }215 }
207 216
208 if (!found) {217 if (!found) {
209 jas_eprintf("error: no code stream found\n");218 jas_logerrorf("error: no code stream found\n");
210 goto error;219 goto error;
211 }220 }
212 221
213 if (!(dec->image = jpc_decode(in, optstr))) {222 if (!(dec->image = jpc_decode(in, optstr))) {
214 jas_eprintf("error: cannot decode code stream\n");223 jas_logerrorf("error: cannot decode code stream\n");
215 goto error;224 goto error;
216 }225 }
217 226
218 /* An IHDR box must be present. */227 /* An IHDR box must be present. */
219 if (!dec->ihdr) {228 if (!dec->ihdr) {
220 jas_eprintf("error: missing IHDR box\n");229 jas_logerrorf("error: missing IHDR box\n");
221 goto error;230 goto error;
222 }231 }
223 232
@@ -225,12 +234,13 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 1 unmodified line
225 the value specified in the code stream? */234 the value specified in the code stream? */
226 if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(jas_uint,235 if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(jas_uint,
227 jas_image_numcmpts(dec->image))) {236 jas_image_numcmpts(dec->image))) {
228 jas_eprintf("warning: number of components mismatch\n");237 jas_logerrorf("error: number of components mismatch (IHDR)\n");
238 goto error;
229 }239 }
230 240
231 /* At least one component must be present. */241 /* At least one component must be present. */
232 if (!jas_image_numcmpts(dec->image)) {242 if (!jas_image_numcmpts(dec->image)) {
233 jas_eprintf("error: no components\n");243 jas_logerrorf("error: no components\n");
234 goto error;244 goto error;
235 }245 }
236 246
@@ -248,21 +258,23 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 11 unmodified lines
248 with the data in the code stream? */258 with the data in the code stream? */
249 if ((samedtype && dec->ihdr->data.ihdr.bpc != JP2_DTYPETOBPC(dtype)) ||259 if ((samedtype && dec->ihdr->data.ihdr.bpc != JP2_DTYPETOBPC(dtype)) ||
250 (!samedtype && dec->ihdr->data.ihdr.bpc != JP2_IHDR_BPCNULL)) {260 (!samedtype && dec->ihdr->data.ihdr.bpc != JP2_IHDR_BPCNULL)) {
251 jas_eprintf("warning: component data type mismatch\n");261 jas_logerrorf("error: component data type mismatch (IHDR)\n");
262 goto error;
252 }263 }
253 264
254 /* Is the compression type supported? */265 /* Is the compression type supported? */
255 if (dec->ihdr->data.ihdr.comptype != JP2_IHDR_COMPTYPE) {266 if (dec->ihdr->data.ihdr.comptype != JP2_IHDR_COMPTYPE) {
256 jas_eprintf("error: unsupported compression type\n");267 jas_logerrorf("error: unsupported compression type\n");
257 goto error;268 goto error;
258 }269 }
259 270
260 if (dec->bpcc) {271 if (dec->bpcc) {
261 /* Is the number of components indicated in the BPCC box272 /* Is the number of components indicated in the BPCC box
262 consistent with the code stream data? */273 consistent with the code stream data? */
263 if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(jas_uint, jas_image_numcmpts(274 if (dec->bpcc->data.bpcc.numcmpts !=
264 dec->image))) {275 JAS_CAST(jas_uint, jas_image_numcmpts(dec->image))) {
265 jas_eprintf("warning: number of components mismatch\n");276 jas_logerrorf("error: number of components mismatch (BPCC)\n");
277 goto error;
266 }278 }
267 /* Is the component data type information indicated in the BPCC279 /* Is the component data type information indicated in the BPCC
268 box consistent with the code stream data? */280 box consistent with the code stream data? */
@@ -271,17 +283,18 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 2 unmodified lines
271 ++i) {283 ++i) {
272 if (jas_image_cmptdtype(dec->image, i) !=284 if (jas_image_cmptdtype(dec->image, i) !=
273 JP2_BPCTODTYPE(dec->bpcc->data.bpcc.bpcs[i])) {285 JP2_BPCTODTYPE(dec->bpcc->data.bpcc.bpcs[i])) {
274 jas_eprintf("warning: component data type mismatch\n");286 jas_logerrorf("error: component data type mismatch (BPCC)\n");
287 goto error;
275 }288 }
276 }289 }
277 } else {290 } else {
278 jas_eprintf("warning: superfluous BPCC box\n");291 jas_logwarnf("warning: superfluous BPCC box\n");
279 }292 }
280 }293 }
281 294
282 /* A COLR box must be present. */295 /* A COLR box must be present. */
283 if (!dec->colr) {296 if (!dec->colr) {
284 jas_eprintf("error: no COLR box\n");297 jas_logerrorf("error: no COLR box\n");
285 goto error;298 goto error;
286 }299 }
287 300
@@ -293,16 +306,17 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 5 unmodified lines
293 iccprof = jas_iccprof_createfrombuf(dec->colr->data.colr.iccp,306 iccprof = jas_iccprof_createfrombuf(dec->colr->data.colr.iccp,
294 dec->colr->data.colr.iccplen);307 dec->colr->data.colr.iccplen);
295 if (!iccprof) {308 if (!iccprof) {
296 jas_eprintf("error: failed to parse ICC profile\n");309 jas_logerrorf("error: failed to parse ICC profile\n");
297 goto error;310 goto error;
298 }311 }
299 jas_iccprof_gethdr(iccprof, &icchdr);312 jas_iccprof_gethdr(iccprof, &icchdr);
300 //jas_eprintf("ICC Profile CS %08x\n", icchdr.colorspc);313 JAS_LOGDEBUGF(2, "ICC Profile CS %08x\n", icchdr.colorspc);
301 jas_image_setclrspc(dec->image, fromiccpcs(icchdr.colorspc));
302 dec->image->cmprof_ = jas_cmprof_createfromiccprof(iccprof);314 dec->image->cmprof_ = jas_cmprof_createfromiccprof(iccprof);
303 if (!dec->image->cmprof_) {315 if (!dec->image->cmprof_) {
304 jas_iccprof_destroy(iccprof);316 jas_image_setclrspc(dec->image, JAS_CLRSPC_UNKNOWN);
305 goto error;317 jas_logwarnf("warning: cannot create CM profile from ICC profile\n");
318 } else {
319 jas_image_setclrspc(dec->image, fromiccpcs(icchdr.colorspc));
306 }320 }
307 jas_iccprof_destroy(iccprof);321 jas_iccprof_destroy(iccprof);
308 break;322 break;
@@ -310,14 +324,14 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 1 unmodified line
310 324
311 /* If a CMAP box is present, a PCLR box must also be present. */325 /* If a CMAP box is present, a PCLR box must also be present. */
312 if (dec->cmap && !dec->pclr) {326 if (dec->cmap && !dec->pclr) {
313 jas_eprintf("warning: missing PCLR box or superfluous CMAP box\n");327 jas_logwarnf("warning: missing PCLR box or superfluous CMAP box\n");
314 jp2_box_destroy(dec->cmap);328 jp2_box_destroy(dec->cmap);
315 dec->cmap = 0;329 dec->cmap = 0;
316 }330 }
317 331
318 /* If a CMAP box is not present, a PCLR box must not be present. */332 /* If a CMAP box is not present, a PCLR box must not be present. */
319 if (!dec->cmap && dec->pclr) {333 if (!dec->cmap && dec->pclr) {
320 jas_eprintf("warning: missing CMAP box or superfluous PCLR box\n");334 jas_logwarnf("warning: missing CMAP box or superfluous PCLR box\n");
321 jp2_box_destroy(dec->pclr);335 jp2_box_destroy(dec->pclr);
322 dec->pclr = 0;336 dec->pclr = 0;
323 }337 }
@@ -333,13 +347,13 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 9 unmodified lines
333 /* Is the component number reasonable? */347 /* Is the component number reasonable? */
334 if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(jas_uint,348 if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(jas_uint,
335 jas_image_numcmpts(dec->image))) {349 jas_image_numcmpts(dec->image))) {
336 jas_eprintf("error: invalid component number in CMAP box\n");350 jas_logerrorf("error: invalid component number in CMAP box\n");
337 goto error;351 goto error;
338 }352 }
339 /* Is the LUT index reasonable? */353 /* Is the LUT index reasonable? */
340 if (dec->cmap->data.cmap.ents[i].pcol >=354 if (dec->cmap->data.cmap.ents[i].pcol >=
341 dec->pclr->data.pclr.numchans) {355 dec->pclr->data.pclr.numchans) {
342 jas_eprintf("error: invalid CMAP LUT index\n");356 jas_logerrorf("error: invalid CMAP LUT index\n");
343 goto error;357 goto error;
344 }358 }
345 }359 }
@@ -348,7 +362,7 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 2 unmodified lines
348 /* Allocate space for the channel-number to component-number LUT. */362 /* Allocate space for the channel-number to component-number LUT. */
349 if (!(dec->chantocmptlut = jas_alloc2(dec->numchans,363 if (!(dec->chantocmptlut = jas_alloc2(dec->numchans,
350 sizeof(uint_fast16_t)))) {364 sizeof(uint_fast16_t)))) {
351 jas_eprintf("error: no memory\n");365 jas_logerrorf("error: no memory\n");
352 goto error;366 goto error;
353 }367 }
354 368
@@ -357,30 +371,48 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 2 unmodified lines
357 dec->chantocmptlut[i] = i;371 dec->chantocmptlut[i] = i;
358 }372 }
359 } else {373 } else {
374 /* Check to ensure that CMAP/PCLR were initialized. */
375 if (!dec->cmap || !dec->pclr) {
376 jas_logerrorf("missing CMAP/PCLR box\n");
377 goto error;
378 }
379
360 cmapd = &dec->cmap->data.cmap;380 cmapd = &dec->cmap->data.cmap;
361 pclrd = &dec->pclr->data.pclr;381 pclrd = &dec->pclr->data.pclr;
382#if 0
383 /* The following code appears to no longer be needed. */
384 cdefd = &dec->cdef->data.cdef;
385#endif
362 for (channo = 0; channo < cmapd->numchans; ++channo) {386 for (channo = 0; channo < cmapd->numchans; ++channo) {
363 cmapent = &cmapd->ents[channo];387 cmapent = &cmapd->ents[channo];
364 if (cmapent->map == JP2_CMAP_DIRECT) {388 if (cmapent->map == JP2_CMAP_DIRECT) {
365 dec->chantocmptlut[channo] = channo;389 dec->chantocmptlut[channo] = channo;
366 } else if (cmapent->map == JP2_CMAP_PALETTE) {390 } else if (cmapent->map == JP2_CMAP_PALETTE) {
367 if (!pclrd->numlutents) {391 if (!pclrd->numlutents) {
392 jas_logerrorf("error: empty LUT\n");
368 goto error;393 goto error;
369 }394 }
370 lutents = jas_alloc2(pclrd->numlutents, sizeof(int_fast32_t));395 if (!(lutents = jas_alloc2(pclrd->numlutents,
371 if (!lutents) {396 sizeof(int_fast32_t)))) {
397 jas_logerrorf("error: cannot allocate LUT\n");
372 goto error;398 goto error;
373 }399 }
374 for (i = 0; i < pclrd->numlutents; ++i) {400 for (i = 0; i < pclrd->numlutents; ++i) {
375 lutents[i] = pclrd->lutdata[cmapent->pcol + i * pclrd->numchans];401 lutents[i] = pclrd->lutdata[cmapent->pcol + i * pclrd->numchans];
376 }402 }
377 newcmptno = jas_image_numcmpts(dec->image);403 newcmptno = jas_image_numcmpts(dec->image);
378 jas_image_depalettize(dec->image, cmapent->cmptno,404 if (jas_image_depalettize(dec->image, cmapent->cmptno,
379 pclrd->numlutents, lutents,405 pclrd->numlutents, lutents,
380 JP2_BPCTODTYPE(pclrd->bpc[cmapent->pcol]), newcmptno);406 JP2_BPCTODTYPE(pclrd->bpc[cmapent->pcol]), newcmptno)) {
407 jas_logerrorf("jas_image_depalettize failed\n");
408 jas_free(lutents);
409 jas_logerrorf("error: depalettize failed\n");
410 goto error;
411 }
381 dec->chantocmptlut[channo] = newcmptno;412 dec->chantocmptlut[channo] = newcmptno;
382 jas_free(lutents);413 jas_free(lutents);
383#if 0414#if 0
415 /* The following code appears to no longer be needed. */
384 if (dec->cdef) {416 if (dec->cdef) {
385 cdefent = jp2_cdef_lookup(cdefd, channo);417 cdefent = jp2_cdef_lookup(cdefd, channo);
386 if (!cdefent) {418 if (!cdefent) {
@@ -390,17 +422,25 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 3 unmodified lines
390 } else {422 } else {
391 jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), 0, channo + 1));423 jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), 0, channo + 1));
392 }424 }
393#else
394 /* suppress -Wunused-but-set-variable */
395 (void)cdefd;
396#endif425#endif
397 } else {426 } else {
398 jas_eprintf("error: invalid MTYP in CMAP box\n");427 jas_logerrorf("error: invalid MTYP in CMAP box\n");
399 goto error;428 goto error;
400 }429 }
401 }430 }
402 }431 }
403 432
433#if 0
434 /* The following code appears to no longer be needed. */
435 /* Ensure that the number of channels being used by the decoder
436 matches the number of image components. */
437 if (dec->numchans != jas_image_numcmpts(dec->image)) {
438 jas_logerrorf("error: mismatch in number of components (%d != %d)\n",
439 dec->numchans, jas_image_numcmpts(dec->image));
440 goto error;
441 }
442#endif
443
404 /* Mark all components as being of unknown type. */444 /* Mark all components as being of unknown type. */
405 445
406 for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) {446 for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) {
@@ -410,20 +450,34 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 3 unmodified lines
410 /* Determine the type of each component. */450 /* Determine the type of each component. */
411 if (dec->cdef) {451 if (dec->cdef) {
412 for (i = 0; i < dec->cdef->data.cdef.numchans; ++i) {452 for (i = 0; i < dec->cdef->data.cdef.numchans; ++i) {
453 uint_fast16_t channo = dec->cdef->data.cdef.ents[i].channo;
413 /* Is the channel number reasonable? */454 /* Is the channel number reasonable? */
414 if (dec->cdef->data.cdef.ents[i].channo >= dec->numchans) {455 if (channo >= dec->numchans) {
415 jas_eprintf("error: invalid channel number in CDEF box\n");456 jas_logerrorf("error: invalid channel number in CDEF box (%d)\n",
457 channo);
416 goto error;458 goto error;
417 }459 }
418 jas_image_setcmpttype(dec->image,460 unsigned compno = dec->chantocmptlut[channo];
419 dec->chantocmptlut[dec->cdef->data.cdef.ents[i].channo],461 if (compno >= jas_image_numcmpts(dec->image)) {
462 jas_logerrorf(
463 "error: invalid component reference in CDEF box (%d)\n",
464 compno);
465 goto error;
466 }
467 jas_image_setcmpttype(dec->image, compno,
420 jp2_getct(jas_image_clrspc(dec->image),468 jp2_getct(jas_image_clrspc(dec->image),
421 dec->cdef->data.cdef.ents[i].type,469 dec->cdef->data.cdef.ents[i].type,
422 dec->cdef->data.cdef.ents[i].assoc));470 dec->cdef->data.cdef.ents[i].assoc));
423 }471 }
424 } else {472 } else {
425 for (i = 0; i < dec->numchans; ++i) {473 for (i = 0; i < dec->numchans; ++i) {
426 jas_image_setcmpttype(dec->image, dec->chantocmptlut[i],474 unsigned compno = dec->chantocmptlut[i];
475 if (compno >= jas_image_numcmpts(dec->image)) {
476 jas_logerrorf(
477 "error: invalid component reference (%d)\n", compno);
478 goto error;
479 }
480 jas_image_setcmpttype(dec->image, compno,
427 jp2_getct(jas_image_clrspc(dec->image), 0, i + 1));481 jp2_getct(jas_image_clrspc(dec->image), 0, i + 1));
428 }482 }
429 }483 }
@@ -437,12 +491,9 @@ jas_image_t *jp2_decode(jas_stream_t *in, const char *optstr) · 7 unmodified lines
437 491
438 /* Ensure that some components survived. */492 /* Ensure that some components survived. */
439 if (!jas_image_numcmpts(dec->image)) {493 if (!jas_image_numcmpts(dec->image)) {
440 jas_eprintf("error: no components\n");494 jas_logerrorf("error: no components\n");
441 goto error;495 goto error;
442 }496 }
443#if 0
444jas_eprintf("no of components is %d\n", jas_image_numcmpts(dec->image));
445#endif
446 497
447 /* Prevent the image from being destroyed later. */498 /* Prevent the image from being destroyed later. */
448 image = dec->image;499 image = dec->image;
@@ -453,6 +504,9 @@ jas_eprintf("no of components is %d\n", jas_image_numcmpts(dec->image)); · 4 unmodified lines
453 return image;504 return image;
454 505
455error:506error:
507 if (image) {
508 jas_image_destroy(image);
509 }
456 if (box) {510 if (box) {
457 jp2_box_destroy(box);511 jp2_box_destroy(box);
458 }512 }
@@ -462,25 +516,25 @@ error: · 3 unmodified lines
462 return 0;516 return 0;
463}517}
464 518
519#define JP2_VALIDATE_LEN JAS_MIN(JP2_JP_LEN + 4, JAS_STREAM_MAXPUTBACK)
465int jp2_validate(jas_stream_t *in)520int jp2_validate(jas_stream_t *in)
466{521{
467 unsigned char buf[JP2_VALIDATELEN];522 unsigned char buf[JP2_VALIDATE_LEN];
468#if 0
469 jas_stream_t *tmpstream;
470 jp2_box_t *box;
471#endif
472
473 assert(JAS_STREAM_MAXPUTBACK >= JP2_VALIDATELEN);
474 523
475 /* Read the validation data (i.e., the data used for detecting524 /* Read the validation data (i.e., the data used for detecting
476 the format). */525 the format). */
477 if (jas_stream_peek(in, buf, sizeof(buf)) != sizeof(buf))526 assert(sizeof(buf) <= JAS_STREAM_MAXPUTBACK);
527 if (jas_stream_peek(in, buf, sizeof(buf)) != sizeof(buf)) {
478 return -1;528 return -1;
529 }
479 530
480 /* Is the box type correct? */531 /* Is the box type correct? */
481 if ((((uint_least32_t)buf[4] << 24) | ((uint_least32_t)buf[5] << 16) | ((uint_least32_t)buf[6] << 8) | (uint_least32_t)buf[7]) !=532 assert(JP2_VALIDATE_LEN >= 8);
482 JP2_BOX_JP)533 if (((JAS_CAST(uint_least32_t, buf[4]) << 24) |
483 {534 (JAS_CAST(uint_least32_t, buf[5]) << 16) |
535 (JAS_CAST(uint_least32_t, buf[6] << 8)) |
536 (JAS_CAST(uint_least32_t, buf[7]))) !=
537 JP2_BOX_JP) {
484 return -1;538 return -1;
485 }539 }
486 540
jp2_enc.c+494−0
@@ -0,0 +1,494 @@
1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2003 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64/*
65 * JP2 Library
66 *
67 * $Id$
68 */
69
70/******************************************************************************\
71* Includes.
72\******************************************************************************/
73
74#include "jasper/jas_image.h"
75#include "jasper/jas_malloc.h"
76#include "jasper/jas_stream.h"
77#include "jasper/jas_cm.h"
78#include "jasper/jas_icc.h"
79#include "jasper/jas_debug.h"
80
81#include "jp2_cod.h"
82
83/******************************************************************************\
84* Function prototypes.
85\******************************************************************************/
86
87static uint_fast32_t jp2_gettypeasoc(int colorspace, int ctype);
88static int clrspctojp2(jas_clrspc_t clrspc);
89
90/******************************************************************************\
91* Functions.
92\******************************************************************************/
93
94int jp2_encode(jas_image_t *image, jas_stream_t *out, const char *optstr)
95{
96 jp2_box_t *box;
97 jp2_ftyp_t *ftyp;
98 jp2_ihdr_t *ihdr;
99 jas_stream_t *tmpstream;
100 int allcmptssame;
101 jp2_bpcc_t *bpcc;
102 long len;
103 uint_fast16_t cmptno;
104 jp2_colr_t *colr;
105 char buf[4096];
106 uint_fast32_t overhead;
107 jp2_cdefchan_t *cdefchanent;
108 jp2_cdef_t *cdef;
109 uint_fast32_t typeasoc;
110 jas_iccprof_t *iccprof;
111 jas_stream_t *iccstream;
112 int pos;
113 int needcdef;
114
115 box = 0;
116 tmpstream = 0;
117 iccstream = 0;
118 iccprof = 0;
119
120 if (jas_image_numcmpts(image) < 1) {
121 jas_logerrorf("image must have at least one component\n");
122 goto error;
123 }
124
125 allcmptssame = 1;
126 const bool sgnd = jas_image_cmptsgnd(image, 0);
127 const unsigned prec = jas_image_cmptprec(image, 0);
128 for (unsigned i = 1; i < jas_image_numcmpts(image); ++i) {
129 if (jas_image_cmptsgnd(image, i) != sgnd ||
130 jas_image_cmptprec(image, i) != prec) {
131 allcmptssame = 0;
132 break;
133 }
134 }
135
136 /* Output the signature box. */
137
138 if (!(box = jp2_box_create(JP2_BOX_JP))) {
139 jas_logerrorf("cannot create JP box\n");
140 goto error;
141 }
142 box->data.jp.magic = JP2_JP_MAGIC;
143 if (jp2_box_put(box, out)) {
144 jas_logerrorf("cannot write JP box\n");
145 goto error;
146 }
147 jp2_box_destroy(box);
148
149 /* Output the file type box. */
150
151 if (!(box = jp2_box_create(JP2_BOX_FTYP))) {
152 jas_logerrorf("cannot create FTYP box\n");
153 goto error;
154 }
155 ftyp = &box->data.ftyp;
156 ftyp->majver = JP2_FTYP_MAJVER;
157 ftyp->minver = JP2_FTYP_MINVER;
158 ftyp->numcompatcodes = 1;
159 ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE;
160 if (jp2_box_put(box, out)) {
161 jas_logerrorf("cannot write FTYP box\n");
162 goto error;
163 }
164 jp2_box_destroy(box);
165 box = 0;
166
167 /*
168 * Generate the data portion of the JP2 header box.
169 * We cannot simply output the header for this box
170 * since we do not yet know the correct value for the length
171 * field.
172 */
173
174 if (!(tmpstream = jas_stream_memopen(0, 0))) {
175 jas_logerrorf("cannot create temporary stream\n");
176 goto error;
177 }
178
179 /* Generate image header box. */
180
181 if (!(box = jp2_box_create(JP2_BOX_IHDR))) {
182 jas_logerrorf("cannot create IHDR box\n");
183 goto error;
184 }
185 ihdr = &box->data.ihdr;
186 ihdr->width = jas_image_width(image);
187 ihdr->height = jas_image_height(image);
188 ihdr->numcmpts = jas_image_numcmpts(image);
189 ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0),
190 jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL;
191 ihdr->comptype = JP2_IHDR_COMPTYPE;
192 ihdr->csunk = 0;
193 ihdr->ipr = 0;
194 if (jp2_box_put(box, tmpstream)) {
195 jas_logerrorf("cannot write IHDR box\n");
196 goto error;
197 }
198 jp2_box_destroy(box);
199
200 /* Generate bits per component box. */
201
202 if (!allcmptssame) {
203 if (!(box = jp2_box_create(JP2_BOX_BPCC))) {
204 jas_logerrorf("cannot create BPCC box\n");
205 goto error;
206 }
207 bpcc = &box->data.bpcc;
208 bpcc->numcmpts = jas_image_numcmpts(image);
209 if (!(bpcc->bpcs = jas_alloc2(bpcc->numcmpts,
210 sizeof(uint_fast8_t)))) {
211 jas_logerrorf("memory allocation failed\n");
212 goto error;
213 }
214 for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) {
215 bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image,
216 cmptno), jas_image_cmptprec(image, cmptno));
217 }
218 if (jp2_box_put(box, tmpstream)) {
219 jas_logerrorf("cannot write BPCC box\n");
220 goto error;
221 }
222 jp2_box_destroy(box);
223 }
224
225 /* Generate color specification box. */
226
227 if (!(box = jp2_box_create(JP2_BOX_COLR))) {
228 jas_logerrorf("cannot create COLR box\n");
229 goto error;
230 }
231 colr = &box->data.colr;
232 switch (jas_image_clrspc(image)) {
233 case JAS_CLRSPC_SRGB:
234 case JAS_CLRSPC_SYCBCR:
235 case JAS_CLRSPC_SGRAY:
236 colr->method = JP2_COLR_ENUM;
237 colr->csid = clrspctojp2(jas_image_clrspc(image));
238 colr->pri = JP2_COLR_PRI;
239 colr->approx = 0;
240 break;
241 default:
242 colr->method = JP2_COLR_ICC;
243 colr->pri = JP2_COLR_PRI;
244 colr->approx = 0;
245 /* Ensure that cmprof_ is not null. */
246 if (!jas_image_cmprof(image)) {
247 jas_logerrorf("CM profile is null\n");
248 goto error;
249 }
250 if (!(iccprof = jas_iccprof_createfromcmprof(
251 jas_image_cmprof(image)))) {
252 jas_logerrorf("cannot create ICC profile\n");
253 goto error;
254 }
255 if (!(iccstream = jas_stream_memopen(0, 0))) {
256 jas_logerrorf("cannot create temporary stream\n");
257 goto error;
258 }
259 if (jas_iccprof_save(iccprof, iccstream)) {
260 jas_logerrorf("cannot write ICC profile\n");
261 goto error;
262 }
263 if ((pos = jas_stream_tell(iccstream)) < 0) {
264 jas_logerrorf("cannot get stream position\n");
265 goto error;
266 }
267 colr->iccplen = pos;
268 if (!(colr->iccp = jas_malloc(pos))) {
269 jas_logerrorf("memory allocation failed\n");
270 goto error;
271 }
272 jas_stream_rewind(iccstream);
273 if (jas_stream_read(iccstream, colr->iccp, colr->iccplen) !=
274 colr->iccplen) {
275 jas_logerrorf("cannot read temporary stream\n");
276 goto error;
277 }
278 jas_stream_close(iccstream);
279 iccstream = 0;
280 jas_iccprof_destroy(iccprof);
281 iccprof = 0;
282 break;
283 }
284 if (jp2_box_put(box, tmpstream)) {
285 jas_logerrorf("cannot write box\n");
286 goto error;
287 }
288 jp2_box_destroy(box);
289
290 needcdef = 1;
291 switch (jas_clrspc_fam(jas_image_clrspc(image))) {
292 case JAS_CLRSPC_FAM_RGB:
293 if (jas_image_numcmpts(image) >= 3 &&
294 jas_image_cmpttype(image, 0) ==
295 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R) &&
296 jas_image_cmpttype(image, 1) ==
297 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G) &&
298 jas_image_cmpttype(image, 2) ==
299 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B))
300 needcdef = 0;
301 break;
302 case JAS_CLRSPC_FAM_YCBCR:
303 if (jas_image_numcmpts(image) >= 3 &&
304 jas_image_cmpttype(image, 0) ==
305 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y) &&
306 jas_image_cmpttype(image, 1) ==
307 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB) &&
308 jas_image_cmpttype(image, 2) ==
309 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR))
310 needcdef = 0;
311 break;
312 case JAS_CLRSPC_FAM_GRAY:
313 if (jas_image_numcmpts(image) >= 1 &&
314 jas_image_cmpttype(image, 0) ==
315 JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y))
316 needcdef = 0;
317 break;
318 default:
319 assert(false);
320 JAS_UNREACHABLE();
321 }
322
323 if (needcdef) {
324 if (!(box = jp2_box_create(JP2_BOX_CDEF))) {
325 jas_logerrorf("cannot create CDEF box\n");
326 goto error;
327 }
328 cdef = &box->data.cdef;
329 cdef->numchans = jas_image_numcmpts(image);
330 cdef->ents = jas_alloc2(cdef->numchans, sizeof(jp2_cdefchan_t));
331 if (!cdef->ents) {
332 goto error;
333 }
334 for (unsigned i = 0; i < jas_image_numcmpts(image); ++i) {
335 cdefchanent = &cdef->ents[i];
336 cdefchanent->channo = i;
337 typeasoc = jp2_gettypeasoc(jas_image_clrspc(image), jas_image_cmpttype(image, i));
338 cdefchanent->type = typeasoc >> 16;
339 cdefchanent->assoc = typeasoc & 0x7fff;
340 }
341 if (jp2_box_put(box, tmpstream)) {
342 jas_logerrorf("cannot write CDEF box\n");
343 goto error;
344 }
345 jp2_box_destroy(box);
346 }
347
348 /* Determine the total length of the JP2 header box. */
349
350 len = jas_stream_tell(tmpstream);
351 jas_stream_rewind(tmpstream);
352
353 /*
354 * Output the JP2 header box and all of the boxes which it contains.
355 */
356
357 if (!(box = jp2_box_create(JP2_BOX_JP2H))) {
358 jas_logerrorf("cannot create JP2H box\n");
359 goto error;
360 }
361 box->len = len + JP2_BOX_HDRLEN(false);
362 if (jp2_box_put(box, out)) {
363 jas_logerrorf("cannot write JP2H box\n");
364 goto error;
365 }
366 jp2_box_destroy(box);
367 box = 0;
368
369 if (jas_stream_copy(out, tmpstream, len)) {
370 jas_logerrorf("cannot copy stream\n");
371 goto error;
372 }
373
374 jas_stream_close(tmpstream);
375 tmpstream = 0;
376
377 /*
378 * Output the contiguous code stream box.
379 */
380
381 if (!(box = jp2_box_create(JP2_BOX_JP2C))) {
382 jas_logerrorf("cannot create JP2C box\n");
383 goto error;
384 }
385 box->len = 0;
386 if (jp2_box_put(box, out)) {
387 jas_logerrorf("cannot write JP2C box\n");
388 goto error;
389 }
390 jp2_box_destroy(box);
391 box = 0;
392
393 /* Output the JPEG-2000 code stream. */
394
395 overhead = jas_stream_getrwcount(out);
396 sprintf(buf, "%s\n_jp2overhead=%lu\n", (optstr ? optstr : ""),
397 (unsigned long) overhead);
398
399 if (jpc_encode(image, out, buf)) {
400 jas_logerrorf("jpc_encode failed\n");
401 goto error;
402 }
403
404 return 0;
405
406error:
407
408 if (iccprof) {
409 jas_iccprof_destroy(iccprof);
410 }
411 if (iccstream) {
412 jas_stream_close(iccstream);
413 }
414 if (box) {
415 jp2_box_destroy(box);
416 }
417 if (tmpstream) {
418 jas_stream_close(tmpstream);
419 }
420 return -1;
421}
422
423static uint_fast32_t jp2_gettypeasoc(int colorspace, int ctype)
424{
425 int type;
426 int asoc;
427
428 if (ctype & JAS_IMAGE_CT_OPACITY) {
429 type = JP2_CDEF_TYPE_OPACITY;
430 asoc = JP2_CDEF_ASOC_ALL;
431 goto done;
432 }
433
434 type = JP2_CDEF_TYPE_UNSPEC;
435 asoc = JP2_CDEF_ASOC_NONE;
436 switch (jas_clrspc_fam(colorspace)) {
437 case JAS_CLRSPC_FAM_RGB:
438 switch (JAS_IMAGE_CT_COLOR(ctype)) {
439 case JAS_IMAGE_CT_RGB_R:
440 type = JP2_CDEF_TYPE_COLOR;
441 asoc = JP2_CDEF_RGB_R;
442 break;
443 case JAS_IMAGE_CT_RGB_G:
444 type = JP2_CDEF_TYPE_COLOR;
445 asoc = JP2_CDEF_RGB_G;
446 break;
447 case JAS_IMAGE_CT_RGB_B:
448 type = JP2_CDEF_TYPE_COLOR;
449 asoc = JP2_CDEF_RGB_B;
450 break;
451 }
452 break;
453 case JAS_CLRSPC_FAM_YCBCR:
454 switch (JAS_IMAGE_CT_COLOR(ctype)) {
455 case JAS_IMAGE_CT_YCBCR_Y:
456 type = JP2_CDEF_TYPE_COLOR;
457 asoc = JP2_CDEF_YCBCR_Y;
458 break;
459 case JAS_IMAGE_CT_YCBCR_CB:
460 type = JP2_CDEF_TYPE_COLOR;
461 asoc = JP2_CDEF_YCBCR_CB;
462 break;
463 case JAS_IMAGE_CT_YCBCR_CR:
464 type = JP2_CDEF_TYPE_COLOR;
465 asoc = JP2_CDEF_YCBCR_CR;
466 break;
467 }
468 break;
469 case JAS_CLRSPC_FAM_GRAY:
470 type = JP2_CDEF_TYPE_COLOR;
471 asoc = JP2_CDEF_GRAY_Y;
472 break;
473 }
474
475done:
476 return (type << 16) | asoc;
477}
478
479static int clrspctojp2(jas_clrspc_t clrspc)
480{
481 switch (clrspc) {
482 case JAS_CLRSPC_SRGB:
483 return JP2_COLR_SRGB;
484 case JAS_CLRSPC_SYCBCR:
485 return JP2_COLR_SYCC;
486 case JAS_CLRSPC_SGRAY:
487 return JP2_COLR_SGRAY;
488 default:
489 assert(false);
490 JAS_UNREACHABLE();
491 }
492 JAS_UNREACHABLE();
493 return -1;
494}
jpc_bs.c+7−4
@@ -166,9 +166,9 @@ static jpc_bitstream_t *jpc_bitstream_alloc() · 165 unmodified lines
166int jpc_bitstream_getbit_func(jpc_bitstream_t *bitstream)166int jpc_bitstream_getbit_func(jpc_bitstream_t *bitstream)
167{167{
168 int ret;168 int ret;
169 JAS_DBGLOG(1000, ("jpc_bitstream_getbit_func(%p)\n", bitstream));169 JAS_LOGDEBUGF(1000, "jpc_bitstream_getbit_func(%p)\n", bitstream);
170 ret = jpc_bitstream_getbit_macro(bitstream);170 ret = jpc_bitstream_getbit_macro(bitstream);
171 JAS_DBGLOG(1000, ("jpc_bitstream_getbit_func -> %d\n", ret));171 JAS_LOGDEBUGF(1000, "jpc_bitstream_getbit_func -> %d\n", ret);
172 return ret;172 return ret;
173}173}
174 174
@@ -176,9 +176,9 @@ int jpc_bitstream_getbit_func(jpc_bitstream_t *bitstream) · 1 unmodified line
176int jpc_bitstream_putbit_func(jpc_bitstream_t *bitstream, int b)176int jpc_bitstream_putbit_func(jpc_bitstream_t *bitstream, int b)
177{177{
178 int ret;178 int ret;
179 JAS_DBGLOG(1000, ("jpc_bitstream_putbit_func(%p, %d)\n", bitstream, b));179 JAS_LOGDEBUGF(1000, "jpc_bitstream_putbit_func(%p, %d)\n", bitstream, b);
180 ret = jpc_bitstream_putbit_macro(bitstream, b);180 ret = jpc_bitstream_putbit_macro(bitstream, b);
181 JAS_DBGLOG(1000, ("jpc_bitstream_putbit_func() -> %d\n", ret));181 JAS_LOGDEBUGF(1000, "jpc_bitstream_putbit_func() -> %d\n", ret);
182 return ret;182 return ret;
183}183}
184 184
@@ -362,6 +362,7 @@ int jpc_bitstream_inalign(jpc_bitstream_t *bitstream, int fillmask, · 177 unmodified lines
362 }362 }
363 if (n > 0) {363 if (n > 0) {
364 if ((u = jpc_bitstream_getbits(bitstream, n)) < 0) {364 if ((u = jpc_bitstream_getbits(bitstream, n)) < 0) {
365 JAS_LOGDEBUGF(1, "jpc_bitstream_inalign failed\n");
365 return -1;366 return -1;
366 }367 }
367 m += n;368 m += n;
@@ -369,6 +370,7 @@ int jpc_bitstream_inalign(jpc_bitstream_t *bitstream, int fillmask, · 1 unmodified line
369 }370 }
370 if ((bitstream->buf_ & 0xff) == 0xff) {371 if ((bitstream->buf_ & 0xff) == 0xff) {
371 if ((u = jpc_bitstream_getbits(bitstream, 7)) < 0) {372 if ((u = jpc_bitstream_getbits(bitstream, 7)) < 0) {
373 JAS_LOGDEBUGF(1, "jpc_bitstream_inalign failed\n");
372 return -1;374 return -1;
373 }375 }
374 v = (v << 7) | u;376 v = (v << 7) | u;
@@ -382,6 +384,7 @@ int jpc_bitstream_inalign(jpc_bitstream_t *bitstream, int fillmask, · 7 unmodified lines
382 }384 }
383 if (((~(v ^ filldata)) & fillmask) != fillmask) {385 if (((~(v ^ filldata)) & fillmask) != fillmask) {
384 /* The actual fill pattern does not match the expected one. */386 /* The actual fill pattern does not match the expected one. */
387 JAS_LOGDEBUGF(1, "jpc_bitstream_inalign failed (mismatch)\n");
385 return 1;388 return 1;
386 }389 }
387 390
jpc_bs.h+2−2
@@ -212,12 +212,12 @@ int jpc_bitstream_putbit_func(jpc_bitstream_t *bitstream, int v); · 211 unmodified lines
212int jpc_bitstream_fillbuf(jpc_bitstream_t *bitstream);212int jpc_bitstream_fillbuf(jpc_bitstream_t *bitstream);
213 213
214#define jpc_bitstream_getbit_macro(bitstream) \214#define jpc_bitstream_getbit_macro(bitstream) \
215 ((--(bitstream)->cnt_ >= 0) ? \215 ( (--(bitstream)->cnt_ >= 0) ? \
216 ((int)(((bitstream)->buf_ >> (bitstream)->cnt_) & 1)) : \216 ((int)(((bitstream)->buf_ >> (bitstream)->cnt_) & 1)) : \
217 jpc_bitstream_fillbuf(bitstream))217 jpc_bitstream_fillbuf(bitstream))
218 218
219#define jpc_bitstream_putbit_macro(bitstream, bit) \219#define jpc_bitstream_putbit_macro(bitstream, bit) \
220 ((--(bitstream)->cnt_ < 0) ? \220 ( (--(bitstream)->cnt_ < 0) ? \
221 ((bitstream)->buf_ = ((bitstream)->buf_ << 8) & 0xffff, \221 ((bitstream)->buf_ = ((bitstream)->buf_ << 8) & 0xffff, \
222 (bitstream)->cnt_ = ((bitstream)->buf_ == 0xff00) ? 6 : 7, \222 (bitstream)->cnt_ = ((bitstream)->buf_ == 0xff00) ? 6 : 7, \
223 (bitstream)->buf_ |= ((bit) & 1) << (bitstream)->cnt_, \223 (bitstream)->buf_ |= ((bit) & 1) << (bitstream)->cnt_, \
jpc_cod.c+109−0
@@ -0,0 +1,109 @@
1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2003 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64/******************************************************************************\
65* Includes.
66\******************************************************************************/
67
68#define JAS_FOR_INTERNAL_USE_ONLY
69
70#include <jasper/jas_config.h>
71#include "jasper/jas_thread.h"
72#include "jasper/jas_debug.h"
73
74#include "jpc_cod.h"
75
76/******************************************************************************\
77*
78\******************************************************************************/
79
80static void jpc_init_helper(void);
81
82#if defined(JAS_THREADS)
83jas_once_flag_t jpc_init_once = JAS_ONCE_FLAG_INIT;
84#else
85int jpc_init_once = 0;
86#endif
87
88/******************************************************************************\
89*
90\******************************************************************************/
91
92void jpc_init(void)
93{
94#if defined(JAS_THREADS)
95 jas_call_once(&jpc_init_once, jpc_init_helper);
96#else
97 if (!jpc_init_once) {
98 jpc_init_helper();
99 jpc_init_once = 1;
100 }
101#endif
102}
103
104static void jpc_init_helper(void)
105{
106 JAS_LOGDEBUGF(10, "jpc_init_helper called\n");
107 jpc_initmqctxs();
108 jpc_initluts();
109}
jpc_cod.h+4−0
@@ -68,6 +68,8 @@ · 67 unmodified lines
68#ifndef JPC_COD_H68#ifndef JPC_COD_H
69#define JPC_COD_H69#define JPC_COD_H
70 70
71#include "jpc_t1cod.h"
72
71/******************************************************************************\73/******************************************************************************\
72* Constants.74* Constants.
73\******************************************************************************/75\******************************************************************************/
@@ -75,4 +77,6 @@ · 1 unmodified line
75/* The nominal word size used by this implementation. */77/* The nominal word size used by this implementation. */
76#define JPC_PREC 3278#define JPC_PREC 32
77 79
80void jpc_init(void);
81
78#endif82#endif
jpc_cs.c+312−77
@@ -94,6 +94,7 @@ typedef struct { · 93 unmodified lines
94 94
95static const jpc_mstabent_t *jpc_mstab_lookup(int id);95static const jpc_mstabent_t *jpc_mstab_lookup(int id);
96 96
97static int jpc_poc_dumpparms(jpc_ms_t *ms);
97static int jpc_poc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);98static int jpc_poc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
98static int jpc_poc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);99static int jpc_poc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
99static void jpc_poc_destroyparms(jpc_ms_t *ms);100static void jpc_poc_destroyparms(jpc_ms_t *ms);
@@ -126,6 +127,20 @@ static int jpc_ppt_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 26 unmodified lines
126static int jpc_crg_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);127static int jpc_crg_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
127static int jpc_com_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);128static int jpc_com_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
128 129
130static int jpc_sot_dumpparms(jpc_ms_t *ms);
131static int jpc_siz_dumpparms(jpc_ms_t *ms);
132static int jpc_cod_dumpparms(jpc_ms_t *ms);
133static int jpc_coc_dumpparms(jpc_ms_t *ms);
134static int jpc_qcd_dumpparms(jpc_ms_t *ms);
135static int jpc_qcc_dumpparms(jpc_ms_t *ms);
136static int jpc_rgn_dumpparms(jpc_ms_t *ms);
137static int jpc_unk_dumpparms(jpc_ms_t *ms);
138static int jpc_sop_dumpparms(jpc_ms_t *ms);
139static int jpc_ppm_dumpparms(jpc_ms_t *ms);
140static int jpc_ppt_dumpparms(jpc_ms_t *ms);
141static int jpc_crg_dumpparms(jpc_ms_t *ms);
142static int jpc_com_dumpparms(jpc_ms_t *ms);
143
129static void jpc_siz_destroyparms(jpc_ms_t *ms);144static void jpc_siz_destroyparms(jpc_ms_t *ms);
130static void jpc_qcd_destroyparms(jpc_ms_t *ms);145static void jpc_qcd_destroyparms(jpc_ms_t *ms);
131static void jpc_qcc_destroyparms(jpc_ms_t *ms);146static void jpc_qcc_destroyparms(jpc_ms_t *ms);
@@ -153,26 +168,40 @@ static int jpc_cox_putcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate, · 21 unmodified lines
153\******************************************************************************/168\******************************************************************************/
154 169
155static const jpc_mstabent_t jpc_mstab[] = {170static const jpc_mstabent_t jpc_mstab[] = {
156 {JPC_MS_SOC, "SOC", {0, 0, 0}},171 {JPC_MS_SOC, "SOC", {0, 0, 0, 0}},
157 {JPC_MS_SOT, "SOT", {0, jpc_sot_getparms, jpc_sot_putparms}},172 {JPC_MS_SOT, "SOT", {0, jpc_sot_getparms, jpc_sot_putparms,
158 {JPC_MS_SOD, "SOD", {0, 0, 0}},173 jpc_sot_dumpparms}},
159 {JPC_MS_EOC, "EOC", {0, 0, 0}},174 {JPC_MS_SOD, "SOD", {0, 0, 0, 0}},
160 {JPC_MS_SIZ, "SIZ", {jpc_siz_destroyparms, jpc_siz_getparms, jpc_siz_putparms}},175 {JPC_MS_EOC, "EOC", {0, 0, 0, 0}},
161 {JPC_MS_COD, "COD", {jpc_cod_destroyparms, jpc_cod_getparms, jpc_cod_putparms}},176 {JPC_MS_SIZ, "SIZ", {jpc_siz_destroyparms, jpc_siz_getparms,
162 {JPC_MS_COC, "COC", {jpc_coc_destroyparms, jpc_coc_getparms, jpc_coc_putparms}},177 jpc_siz_putparms, jpc_siz_dumpparms}},
163 {JPC_MS_RGN, "RGN", {0, jpc_rgn_getparms, jpc_rgn_putparms}},178 {JPC_MS_COD, "COD", {jpc_cod_destroyparms, jpc_cod_getparms,
164 {JPC_MS_QCD, "QCD", {jpc_qcd_destroyparms, jpc_qcd_getparms, jpc_qcd_putparms}},179 jpc_cod_putparms, jpc_cod_dumpparms}},
165 {JPC_MS_QCC, "QCC", {jpc_qcc_destroyparms, jpc_qcc_getparms, jpc_qcc_putparms}},180 {JPC_MS_COC, "COC", {jpc_coc_destroyparms, jpc_coc_getparms,
166 {JPC_MS_POC, "POC", {jpc_poc_destroyparms, jpc_poc_getparms, jpc_poc_putparms}},181 jpc_coc_putparms, jpc_coc_dumpparms}},
167 {JPC_MS_TLM, "TLM", {jpc_unk_destroyparms, jpc_unk_getparms, jpc_unk_putparms,}},182 {JPC_MS_RGN, "RGN", {0, jpc_rgn_getparms, jpc_rgn_putparms,
168 {JPC_MS_PLM, "PLM", {jpc_unk_destroyparms, jpc_unk_getparms, jpc_unk_putparms}},183 jpc_rgn_dumpparms}},
169 {JPC_MS_PPM, "PPM", {jpc_ppm_destroyparms, jpc_ppm_getparms, jpc_ppm_putparms}},184 {JPC_MS_QCD, "QCD", {jpc_qcd_destroyparms, jpc_qcd_getparms,
170 {JPC_MS_PPT, "PPT", {jpc_ppt_destroyparms, jpc_ppt_getparms, jpc_ppt_putparms}},185 jpc_qcd_putparms, jpc_qcd_dumpparms}},
171 {JPC_MS_SOP, "SOP", {0, jpc_sop_getparms, jpc_sop_putparms}},186 {JPC_MS_QCC, "QCC", {jpc_qcc_destroyparms, jpc_qcc_getparms,
172 {JPC_MS_EPH, "EPH", {0, 0, 0}},187 jpc_qcc_putparms, jpc_qcc_dumpparms}},
173 {JPC_MS_CRG, "CRG", {jpc_crg_destroyparms, jpc_crg_getparms, jpc_crg_putparms}},188 {JPC_MS_POC, "POC", {jpc_poc_destroyparms, jpc_poc_getparms,
174 {JPC_MS_COM, "COM", {jpc_com_destroyparms, jpc_com_getparms, jpc_com_putparms}},189 jpc_poc_putparms, jpc_poc_dumpparms}},
175 {-1, "UNKNOWN", {jpc_unk_destroyparms, jpc_unk_getparms, jpc_unk_putparms}}190 {JPC_MS_TLM, "TLM", {jpc_unk_destroyparms, jpc_unk_getparms, jpc_unk_putparms, 0}},
191 {JPC_MS_PLM, "PLM", {jpc_unk_destroyparms, jpc_unk_getparms, jpc_unk_putparms, 0}},
192 {JPC_MS_PPM, "PPM", {jpc_ppm_destroyparms, jpc_ppm_getparms,
193 jpc_ppm_putparms, jpc_ppm_dumpparms}},
194 {JPC_MS_PPT, "PPT", {jpc_ppt_destroyparms, jpc_ppt_getparms,
195 jpc_ppt_putparms, jpc_ppt_dumpparms}},
196 {JPC_MS_SOP, "SOP", {0, jpc_sop_getparms, jpc_sop_putparms,
197 jpc_sop_dumpparms}},
198 {JPC_MS_EPH, "EPH", {0, 0, 0, 0}},
199 {JPC_MS_CRG, "CRG", {jpc_crg_destroyparms, jpc_crg_getparms,
200 jpc_crg_putparms, jpc_crg_dumpparms}},
201 {JPC_MS_COM, "COM", {jpc_com_destroyparms, jpc_com_getparms,
202 jpc_com_putparms, jpc_com_dumpparms}},
203 {-1, "UNKNOWN", {jpc_unk_destroyparms, jpc_unk_getparms,
204 jpc_unk_putparms, jpc_unk_dumpparms}}
176};205};
177 206
178/******************************************************************************\207/******************************************************************************\
@@ -238,7 +267,7 @@ jpc_ms_t *jpc_getms(jas_stream_t *in, jpc_cstate_t *cstate) · 59 unmodified lines
238 return 0;267 return 0;
239 }268 }
240 if (jas_stream_copy(tmpstream, in, ms->len) ||269 if (jas_stream_copy(tmpstream, in, ms->len) ||
241 jas_stream_seek(tmpstream, 0, 0) < 0) {270 jas_stream_seek(tmpstream, 0, SEEK_SET) < 0) {
242 jas_stream_close(tmpstream);271 jas_stream_close(tmpstream);
243 jpc_ms_destroy(ms);272 jpc_ms_destroy(ms);
244 return 0;273 return 0;
@@ -251,8 +280,12 @@ jpc_ms_t *jpc_getms(jas_stream_t *in, jpc_cstate_t *cstate) · 6 unmodified lines
251 return 0;280 return 0;
252 }281 }
253 282
283 if (jas_get_debug_level() > 0) {
284 jpc_ms_dump(ms);
285 }
286
254 if (JAS_CAST(jas_ulong, jas_stream_tell(tmpstream)) != ms->len) {287 if (JAS_CAST(jas_ulong, jas_stream_tell(tmpstream)) != ms->len) {
255 jas_eprintf(288 jas_logwarnf(
256 "warning: trailing garbage in marker segment (%ld bytes)\n",289 "warning: trailing garbage in marker segment (%ld bytes)\n",
257 ms->len - jas_stream_tell(tmpstream));290 ms->len - jas_stream_tell(tmpstream));
258 }291 }
@@ -263,6 +296,10 @@ jpc_ms_t *jpc_getms(jas_stream_t *in, jpc_cstate_t *cstate) · 4 unmodified lines
263 } else {296 } else {
264 /* There are no marker segment parameters. */297 /* There are no marker segment parameters. */
265 ms->len = 0;298 ms->len = 0;
299
300 if (jas_get_debug_level() > 0) {
301 jpc_ms_dump(ms);
302 }
266 }303 }
267 304
268 /* Update the code stream state information based on the type of305 /* Update the code stream state information based on the type of
@@ -306,7 +343,7 @@ int jpc_putms(jas_stream_t *out, jpc_cstate_t *cstate, jpc_ms_t *ms) · 37 unmodified lines
306 ms->len = len;343 ms->len = len;
307 /* Write the marker segment length and parameter data to344 /* Write the marker segment length and parameter data to
308 the output stream. */345 the output stream. */
309 if (jas_stream_seek(tmpstream, 0, 0) < 0 ||346 if (jas_stream_seek(tmpstream, 0, SEEK_SET) < 0 ||
310 jpc_putuint16(out, ms->len + 2) ||347 jpc_putuint16(out, ms->len + 2) ||
311 jas_stream_copy(out, tmpstream, ms->len) < 0) {348 jas_stream_copy(out, tmpstream, ms->len) < 0) {
312 jas_stream_close(tmpstream);349 jas_stream_close(tmpstream);
@@ -322,6 +359,10 @@ int jpc_putms(jas_stream_t *out, jpc_cstate_t *cstate, jpc_ms_t *ms) · 9 unmodified lines
322 cstate->numcomps = ms->parms.siz.numcomps;359 cstate->numcomps = ms->parms.siz.numcomps;
323 }360 }
324 361
362 if (jas_get_debug_level() > 0) {
363 jpc_ms_dump(ms);
364 }
365
325 return 0;366 return 0;
326}367}
327 368
@@ -355,6 +396,24 @@ void jpc_ms_destroy(jpc_ms_t *ms) · 27 unmodified lines
355 jas_free(ms);396 jas_free(ms);
356}397}
357 398
399/* Dump a marker segment to a stream for debugging. */
400void jpc_ms_dump(jpc_ms_t *ms)
401{
402 const jpc_mstabent_t *mstabent;
403 mstabent = jpc_mstab_lookup(ms->id);
404 jas_logprintf("type = 0x%04"PRIxFAST16" (%s);", ms->id, mstabent->name);
405 if (JPC_MS_HASPARMS(ms->id)) {
406 jas_logprintf(" len = %"PRIuFAST16";", ms->len + 2);
407 if (ms->ops->dumpparms) {
408 (*ms->ops->dumpparms)(ms);
409 } else {
410 jas_logprintf("\n");
411 }
412 } else {
413 jas_logprintf("\n");
414 }
415}
416
358/******************************************************************************\417/******************************************************************************\
359* SOT marker segment operations.418* SOT marker segment operations.
360\******************************************************************************/419\******************************************************************************/
@@ -363,8 +422,7 @@ static int jpc_sot_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in · 2 unmodified lines
363{422{
364 jpc_sot_t *sot = &ms->parms.sot;423 jpc_sot_t *sot = &ms->parms.sot;
365 424
366 /* Eliminate compiler warning about unused variables. */425 JAS_UNUSED(cstate);
367 (void)cstate;
368 426
369 if (jpc_getuint16(in, &sot->tileno) ||427 if (jpc_getuint16(in, &sot->tileno) ||
370 jpc_getuint32(in, &sot->len) ||428 jpc_getuint32(in, &sot->len) ||
@@ -385,8 +443,7 @@ static int jpc_sot_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 14 unmodified lines
385{443{
386 jpc_sot_t *sot = &ms->parms.sot;444 jpc_sot_t *sot = &ms->parms.sot;
387 445
388 /* Eliminate compiler warning about unused variables. */446 JAS_UNUSED(cstate);
389 (void)cstate;
390 447
391 if (jpc_putuint16(out, sot->tileno) ||448 if (jpc_putuint16(out, sot->tileno) ||
392 jpc_putuint32(out, sot->len) ||449 jpc_putuint32(out, sot->len) ||
@@ -397,6 +454,15 @@ static int jpc_sot_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 4 unmodified lines
397 return 0;454 return 0;
398}455}
399 456
457static int jpc_sot_dumpparms(jpc_ms_t *ms)
458{
459 jpc_sot_t *sot = &ms->parms.sot;
460 jas_logprintf(
461 "tileno = %"PRIuFAST16"; len = %"PRIuFAST32"; partno = %d; numparts = %d\n",
462 sot->tileno, sot->len, sot->partno, sot->numparts);
463 return 0;
464}
465
400/******************************************************************************\466/******************************************************************************\
401* SIZ marker segment operations.467* SIZ marker segment operations.
402\******************************************************************************/468\******************************************************************************/
@@ -418,8 +484,7 @@ static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, · 15 unmodified lines
418 484
419 siz->comps = 0;485 siz->comps = 0;
420 486
421 /* Eliminate compiler warning about unused variables. */487 JAS_UNUSED(cstate);
422 (void)cstate;
423 488
424 if (jpc_getuint16(in, &siz->caps) ||489 if (jpc_getuint16(in, &siz->caps) ||
425 jpc_getuint32(in, &siz->width) ||490 jpc_getuint32(in, &siz->width) ||
@@ -434,31 +499,31 @@ static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, · 8 unmodified lines
434 goto error;499 goto error;
435 }500 }
436 if (!siz->width || !siz->height) {501 if (!siz->width || !siz->height) {
437 jas_eprintf("reference grid cannot have zero area\n");502 jas_logerrorf("reference grid cannot have zero area\n");
438 goto error;503 goto error;
439 }504 }
440 if (!siz->tilewidth || !siz->tileheight) {505 if (!siz->tilewidth || !siz->tileheight) {
441 jas_eprintf("tile cannot have zero area\n");506 jas_logerrorf("tile cannot have zero area\n");
442 goto error;507 goto error;
443 }508 }
444 if (!siz->numcomps || siz->numcomps > 16384) {509 if (!siz->numcomps || siz->numcomps > 16384) {
445 jas_eprintf("number of components not in permissible range\n");510 jas_logerrorf("number of components not in permissible range\n");
446 goto error;511 goto error;
447 }512 }
448 if (siz->xoff >= siz->width) {513 if (siz->xoff >= siz->width) {
449 jas_eprintf("XOsiz not in permissible range\n");514 jas_logerrorf("XOsiz not in permissible range\n");
450 goto error;515 goto error;
451 }516 }
452 if (siz->yoff >= siz->height) {517 if (siz->yoff >= siz->height) {
453 jas_eprintf("YOsiz not in permissible range\n");518 jas_logerrorf("YOsiz not in permissible range\n");
454 goto error;519 goto error;
455 }520 }
456 if (siz->tilexoff > siz->xoff || siz->tilexoff + siz->tilewidth <= siz->xoff) {521 if (siz->tilexoff > siz->xoff || siz->tilexoff + siz->tilewidth <= siz->xoff) {
457 jas_eprintf("XTOsiz not in permissible range\n");522 jas_logerrorf("XTOsiz not in permissible range\n");
458 goto error;523 goto error;
459 }524 }
460 if (siz->tileyoff > siz->yoff || siz->tileyoff + siz->tileheight <= siz->yoff) {525 if (siz->tileyoff > siz->yoff || siz->tileyoff + siz->tileheight <= siz->yoff) {
461 jas_eprintf("YTOsiz not in permissible range\n");526 jas_logerrorf("YTOsiz not in permissible range\n");
462 goto error;527 goto error;
463 }528 }
464 529
@@ -472,11 +537,11 @@ static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, · 7 unmodified lines
472 goto error;537 goto error;
473 }538 }
474 if (siz->comps[i].hsamp == 0) {539 if (siz->comps[i].hsamp == 0) {
475 jas_eprintf("invalid XRsiz value %d\n", siz->comps[i].hsamp);540 jas_logerrorf("invalid XRsiz value %d\n", siz->comps[i].hsamp);
476 goto error;541 goto error;
477 }542 }
478 if (siz->comps[i].vsamp == 0) {543 if (siz->comps[i].vsamp == 0) {
479 jas_eprintf("invalid YRsiz value %d\n", siz->comps[i].vsamp);544 jas_logerrorf("invalid YRsiz value %d\n", siz->comps[i].vsamp);
480 goto error;545 goto error;
481 }546 }
482 siz->comps[i].sgnd = (tmp >> 7) & 1;547 siz->comps[i].sgnd = (tmp >> 7) & 1;
@@ -485,7 +550,7 @@ static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, · 2 unmodified lines
485 samples and 2 bits for signed samples */550 samples and 2 bits for signed samples */
486 if (siz->comps[i].prec < 1U + siz->comps[i].sgnd ||551 if (siz->comps[i].prec < 1U + siz->comps[i].sgnd ||
487 siz->comps[i].prec > 38) {552 siz->comps[i].prec > 38) {
488 jas_eprintf("invalid component bit depth %d\n", siz->comps[i].prec);553 jas_logerrorf("invalid component bit depth %d\n", siz->comps[i].prec);
489 goto error;554 goto error;
490 }555 }
491 }556 }
@@ -506,8 +571,7 @@ static int jpc_siz_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 14 unmodified lines
506 jpc_siz_t *siz = &ms->parms.siz;571 jpc_siz_t *siz = &ms->parms.siz;
507 unsigned int i;572 unsigned int i;
508 573
509 /* Eliminate compiler warning about unused variables. */574 JAS_UNUSED(cstate);
510 (void)cstate;
511 575
512 assert(siz->width && siz->height && siz->tilewidth &&576 assert(siz->width && siz->height && siz->tilewidth &&
513 siz->tileheight && siz->numcomps);577 siz->tileheight && siz->numcomps);
@@ -534,6 +598,26 @@ static int jpc_siz_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 20 unmodified lines
534 return 0;598 return 0;
535}599}
536 600
601static int jpc_siz_dumpparms(jpc_ms_t *ms)
602{
603 jpc_siz_t *siz = &ms->parms.siz;
604 unsigned int i;
605 jas_logprintf("caps = 0x%02"PRIxFAST16";\n", siz->caps);
606 jas_logprintf("width = %"PRIuFAST32"; height = %"PRIuFAST32"; xoff = %"PRIuFAST32"; yoff = %" PRIuFAST32 ";\n",
607 siz->width, siz->height, siz->xoff, siz->yoff);
608 jas_logprintf("tilewidth = %"PRIuFAST32"; tileheight = %"PRIuFAST32"; "
609 "tilexoff = %"PRIuFAST32"; tileyoff = %" PRIuFAST32 ";\n",
610 siz->tilewidth, siz->tileheight, siz->tilexoff, siz->tileyoff);
611 jas_logprintf("numcomps = %"PRIuFAST16";\n", siz->numcomps);
612 for (i = 0; i < siz->numcomps; ++i) {
613 jas_logprintf("prec[%d] = %d; sgnd[%d] = %d; hsamp[%d] = %d; "
614 "vsamp[%d] = %d\n", i, siz->comps[i].prec, i,
615 siz->comps[i].sgnd, i, siz->comps[i].hsamp, i,
616 siz->comps[i].vsamp);
617 }
618 return 0;
619}
620
537/******************************************************************************\621/******************************************************************************\
538* COD marker segment operations.622* COD marker segment operations.
539\******************************************************************************/623\******************************************************************************/
@@ -587,6 +671,28 @@ static int jpc_cod_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 47 unmodified lines
587 return 0;671 return 0;
588}672}
589 673
674static int jpc_cod_dumpparms(jpc_ms_t *ms)
675{
676 jpc_cod_t *cod = &ms->parms.cod;
677 int i;
678 jas_logprintf("csty = 0x%02x;\n", cod->compparms.csty);
679 jas_logprintf("numdlvls = %d; qmfbid = %d; mctrans = %d\n",
680 cod->compparms.numdlvls, cod->compparms.qmfbid, cod->mctrans);
681 jas_logprintf("prg = %d; numlyrs = %"PRIuFAST16";\n",
682 cod->prg, cod->numlyrs);
683 jas_logprintf("cblkwidthval = %d; cblkheightval = %d; "
684 "cblksty = 0x%02x;\n", cod->compparms.cblkwidthval, cod->compparms.cblkheightval,
685 cod->compparms.cblksty);
686 if (cod->csty & JPC_COX_PRT) {
687 for (i = 0; i < cod->compparms.numrlvls; ++i) {
688 jas_logprintf("prcwidth[%d] = %d, prcheight[%d] = %d\n",
689 i, cod->compparms.rlvls[i].parwidthval,
690 i, cod->compparms.rlvls[i].parheightval);
691 }
692 }
693 return 0;
694}
695
590/******************************************************************************\696/******************************************************************************\
591* COC marker segment operations.697* COC marker segment operations.
592\******************************************************************************/698\******************************************************************************/
@@ -647,14 +753,23 @@ static int jpc_coc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 54 unmodified lines
647 return 0;753 return 0;
648}754}
649 755
756static int jpc_coc_dumpparms(jpc_ms_t *ms)
757{
758 jpc_coc_t *coc = &ms->parms.coc;
759 jas_logprintf("compno = %"PRIuFAST16"; csty = 0x%02x; numdlvls = %d;\n",
760 coc->compno, coc->compparms.csty, coc->compparms.numdlvls);
761 jas_logprintf("cblkwidthval = %d; cblkheightval = %d; "
762 "cblksty = 0x%02x; qmfbid = %d;\n", coc->compparms.cblkwidthval,
763 coc->compparms.cblkheightval, coc->compparms.cblksty, coc->compparms.qmfbid);
764 return 0;
765}
650/******************************************************************************\766/******************************************************************************\
651* COD/COC marker segment operation helper functions.767* COD/COC marker segment operation helper functions.
652\******************************************************************************/768\******************************************************************************/
653 769
654static void jpc_cox_destroycompparms(jpc_coxcp_t *compparms)770static void jpc_cox_destroycompparms(jpc_coxcp_t *compparms)
655{771{
656 /* Eliminate compiler warning about unused variables. */772 JAS_UNUSED(compparms);
657 USED(compparms);
658}773}
659 774
660static int jpc_cox_getcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate,775static int jpc_cox_getcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
@@ -663,9 +778,8 @@ static int jpc_cox_getcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate, · 2 unmodified lines
663 uint_fast8_t tmp;778 uint_fast8_t tmp;
664 int i;779 int i;
665 780
666 /* Eliminate compiler warning about unused variables. */781 JAS_UNUSED(ms);
667 USED(ms);782 JAS_UNUSED(cstate);
668 USED(cstate);
669 783
670 if (jpc_getuint8(in, &compparms->numdlvls) ||784 if (jpc_getuint8(in, &compparms->numdlvls) ||
671 jpc_getuint8(in, &compparms->cblkwidthval) ||785 jpc_getuint8(in, &compparms->cblkwidthval) ||
@@ -711,9 +825,8 @@ static int jpc_cox_putcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate, · 39 unmodified lines
711 int i;825 int i;
712 assert(compparms->numdlvls <= 32);826 assert(compparms->numdlvls <= 32);
713 827
714 /* Eliminate compiler warning about unused variables. */828 JAS_UNUSED(ms);
715 USED(ms);829 JAS_UNUSED(cstate);
716 USED(cstate);
717 830
718 if (jpc_putuint8(out, compparms->numdlvls) ||831 if (jpc_putuint8(out, compparms->numdlvls) ||
719 jpc_putuint8(out, compparms->cblkwidthval) ||832 jpc_putuint8(out, compparms->cblkwidthval) ||
@@ -778,6 +891,14 @@ static int jpc_rgn_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 58 unmodified lines
778 return 0;891 return 0;
779}892}
780 893
894static int jpc_rgn_dumpparms(jpc_ms_t *ms)
895{
896 jpc_rgn_t *rgn = &ms->parms.rgn;
897 jas_logprintf("compno = %"PRIuFAST16"; roisty = %d; roishift = %d\n",
898 rgn->compno, rgn->roisty, rgn->roishift);
899 return 0;
900}
901
781/******************************************************************************\902/******************************************************************************\
782* QCD marker segment operations.903* QCD marker segment operations.
783\******************************************************************************/904\******************************************************************************/
@@ -800,6 +921,20 @@ static int jpc_qcd_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 16 unmodified lines
800 return jpc_qcx_putcompparms(compparms, cstate, out);921 return jpc_qcx_putcompparms(compparms, cstate, out);
801}922}
802 923
924static int jpc_qcd_dumpparms(jpc_ms_t *ms)
925{
926 jpc_qcd_t *qcd = &ms->parms.qcd;
927 int i;
928 jas_logprintf("qntsty = %d; numguard = %d; numstepsizes = %d\n",
929 (int) qcd->compparms.qntsty, qcd->compparms.numguard, qcd->compparms.numstepsizes);
930 for (i = 0; i < qcd->compparms.numstepsizes; ++i) {
931 jas_logprintf("expn[%d] = 0x%04x; mant[%d] = 0x%04x;\n",
932 i, JAS_CAST(unsigned, JPC_QCX_GETEXPN(qcd->compparms.stepsizes[i])),
933 i, JAS_CAST(unsigned, JPC_QCX_GETMANT(qcd->compparms.stepsizes[i])));
934 }
935 return 0;
936}
937
803/******************************************************************************\938/******************************************************************************\
804* QCC marker segment operations.939* QCC marker segment operations.
805\******************************************************************************/940\******************************************************************************/
@@ -856,6 +991,21 @@ static int jpc_qcc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 50 unmodified lines
856 return 0;991 return 0;
857}992}
858 993
994static int jpc_qcc_dumpparms(jpc_ms_t *ms)
995{
996 jpc_qcc_t *qcc = &ms->parms.qcc;
997 int i;
998 jas_logprintf("compno = %"PRIuFAST16"; qntsty = %d; numguard = %d; "
999 "numstepsizes = %d\n", qcc->compno, qcc->compparms.qntsty, qcc->compparms.numguard,
1000 qcc->compparms.numstepsizes);
1001 for (i = 0; i < qcc->compparms.numstepsizes; ++i) {
1002 jas_logprintf("expn[%d] = 0x%04x; mant[%d] = 0x%04x;\n",
1003 i, (unsigned) JPC_QCX_GETEXPN(qcc->compparms.stepsizes[i]),
1004 i, (unsigned) JPC_QCX_GETMANT(qcc->compparms.stepsizes[i]));
1005 }
1006 return 0;
1007}
1008
859/******************************************************************************\1009/******************************************************************************\
860* QCD/QCC marker segment helper functions.1010* QCD/QCC marker segment helper functions.
861\******************************************************************************/1011\******************************************************************************/
@@ -874,8 +1024,7 @@ static int jpc_qcx_getcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate, · 12 unmodified lines
874 int n;1024 int n;
875 int i;1025 int i;
876 1026
877 /* Eliminate compiler warning about unused variables. */1027 JAS_UNUSED(cstate);
878 (void)cstate;
879 1028
880 n = 0;1029 n = 0;
881 if (jpc_getuint8(in, &tmp)) {1030 if (jpc_getuint8(in, &tmp)) {
@@ -936,8 +1085,7 @@ static int jpc_qcx_putcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate, · 54 unmodified lines
936{1085{
937 int i;1086 int i;
938 1087
939 /* Eliminate compiler warning about unused variables. */1088 JAS_UNUSED(cstate);
940 (void)cstate;
941 1089
942 if (jpc_putuint8(out, ((compparms->numguard & 7) << 5) | compparms->qntsty)) {1090 if (jpc_putuint8(out, ((compparms->numguard & 7) << 5) | compparms->qntsty)) {
943 return -1;1091 return -1;
@@ -965,8 +1113,7 @@ static int jpc_sop_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in · 21 unmodified lines
965{1113{
966 jpc_sop_t *sop = &ms->parms.sop;1114 jpc_sop_t *sop = &ms->parms.sop;
967 1115
968 /* Eliminate compiler warning about unused variable. */1116 JAS_UNUSED(cstate);
969 (void)cstate;
970 1117
971 if (jpc_getuint16(in, &sop->seqno)) {1118 if (jpc_getuint16(in, &sop->seqno)) {
972 return -1;1119 return -1;
@@ -978,8 +1125,7 @@ static int jpc_sop_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 5 unmodified lines
978{1125{
979 jpc_sop_t *sop = &ms->parms.sop;1126 jpc_sop_t *sop = &ms->parms.sop;
980 1127
981 /* Eliminate compiler warning about unused variable. */1128 JAS_UNUSED(cstate);
982 (void)cstate;
983 1129
984 if (jpc_putuint16(out, sop->seqno)) {1130 if (jpc_putuint16(out, sop->seqno)) {
985 return -1;1131 return -1;
@@ -987,6 +1133,13 @@ static int jpc_sop_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 1 unmodified line
987 return 0;1133 return 0;
988}1134}
989 1135
1136static int jpc_sop_dumpparms(jpc_ms_t *ms)
1137{
1138 jpc_sop_t *sop = &ms->parms.sop;
1139 jas_logprintf("seqno = %"PRIuFAST16";\n", sop->seqno);
1140 return 0;
1141}
1142
990/******************************************************************************\1143/******************************************************************************\
991* PPM marker segment operations.1144* PPM marker segment operations.
992\******************************************************************************/1145\******************************************************************************/
@@ -1003,8 +1156,7 @@ static int jpc_ppm_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in · 10 unmodified lines
1003{1156{
1004 jpc_ppm_t *ppm = &ms->parms.ppm;1157 jpc_ppm_t *ppm = &ms->parms.ppm;
1005 1158
1006 /* Eliminate compiler warning about unused variables. */1159 JAS_UNUSED(cstate);
1007 (void)cstate;
1008 1160
1009 ppm->data = 0;1161 ppm->data = 0;
1010 1162
@@ -1037,8 +1189,7 @@ static int jpc_ppm_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 26 unmodified lines
1037{1189{
1038 jpc_ppm_t *ppm = &ms->parms.ppm;1190 jpc_ppm_t *ppm = &ms->parms.ppm;
1039 1191
1040 /* Eliminate compiler warning about unused variables. */1192 JAS_UNUSED(cstate);
1041 (void)cstate;
1042 1193
1043 if (JAS_CAST(jas_uint, jas_stream_write(out, (char *) ppm->data, ppm->len)) != ppm->len) {1194 if (JAS_CAST(jas_uint, jas_stream_write(out, (char *) ppm->data, ppm->len)) != ppm->len) {
1044 return -1;1195 return -1;
@@ -1046,6 +1197,17 @@ static int jpc_ppm_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 1 unmodified line
1046 return 0;1197 return 0;
1047}1198}
1048 1199
1200static int jpc_ppm_dumpparms(jpc_ms_t *ms)
1201{
1202 jpc_ppm_t *ppm = &ms->parms.ppm;
1203 jas_logprintf("ind=%d; len = %"PRIuFAST16";\n", ppm->ind, ppm->len);
1204 if (ppm->len > 0) {
1205 jas_logprintf("data =\n");
1206 jas_logmemdump(ppm->data, ppm->len);
1207 }
1208 return 0;
1209}
1210
1049/******************************************************************************\1211/******************************************************************************\
1050* PPT marker segment operations.1212* PPT marker segment operations.
1051\******************************************************************************/1213\******************************************************************************/
@@ -1062,8 +1224,7 @@ static int jpc_ppt_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in · 10 unmodified lines
1062{1224{
1063 jpc_ppt_t *ppt = &ms->parms.ppt;1225 jpc_ppt_t *ppt = &ms->parms.ppt;
1064 1226
1065 /* Eliminate compiler warning about unused variables. */1227 JAS_UNUSED(cstate);
1066 (void)cstate;
1067 1228
1068 ppt->data = 0;1229 ppt->data = 0;
1069 1230
@@ -1095,8 +1256,7 @@ static int jpc_ppt_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 25 unmodified lines
1095{1256{
1096 jpc_ppt_t *ppt = &ms->parms.ppt;1257 jpc_ppt_t *ppt = &ms->parms.ppt;
1097 1258
1098 /* Eliminate compiler warning about unused variable. */1259 JAS_UNUSED(cstate);
1099 (void)cstate;
1100 1260
1101 if (jpc_putuint8(out, ppt->ind)) {1261 if (jpc_putuint8(out, ppt->ind)) {
1102 return -1;1262 return -1;
@@ -1107,6 +1267,17 @@ static int jpc_ppt_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 4 unmodified lines
1107 return 0;1267 return 0;
1108}1268}
1109 1269
1270static int jpc_ppt_dumpparms(jpc_ms_t *ms)
1271{
1272 jpc_ppt_t *ppt = &ms->parms.ppt;
1273 jas_logprintf("ind=%d; len = %"PRIuFAST32";\n", ppt->ind, ppt->len);
1274 if (ppt->len > 0) {
1275 jas_logprintf("data =\n");
1276 jas_logmemdump(ppt->data, ppt->len);
1277 }
1278 return 0;
1279}
1280
1110/******************************************************************************\1281/******************************************************************************\
1111* POC marker segment operations.1282* POC marker segment operations.
1112\******************************************************************************/1283\******************************************************************************/
@@ -1197,6 +1368,23 @@ static int jpc_poc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 84 unmodified lines
1197 return 0;1368 return 0;
1198}1369}
1199 1370
1371static int jpc_poc_dumpparms(jpc_ms_t *ms)
1372{
1373 jpc_poc_t *poc = &ms->parms.poc;
1374 jpc_pocpchg_t *pchg;
1375 int pchgno;
1376 for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs;
1377 ++pchgno, ++pchg) {
1378 jas_logprintf("po[%d] = %d; ", pchgno, pchg->prgord);
1379 jas_logprintf("cs[%d] = %"PRIuFAST16"; ce[%d] = %"PRIuFAST16"; ",
1380 pchgno, pchg->compnostart, pchgno, pchg->compnoend);
1381 jas_logprintf("rs[%d] = %d; re[%d] = %d; ",
1382 pchgno, pchg->rlvlnostart, pchgno, pchg->rlvlnoend);
1383 jas_logprintf("le[%d] = %"PRIuFAST16"\n", pchgno, pchg->lyrnoend);
1384 }
1385 return 0;
1386}
1387
1200/******************************************************************************\1388/******************************************************************************\
1201* CRG marker segment operations.1389* CRG marker segment operations.
1202\******************************************************************************/1390\******************************************************************************/
@@ -1235,8 +1423,7 @@ static int jpc_crg_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 32 unmodified lines
1235 int compno;1423 int compno;
1236 jpc_crgcomp_t *comp;1424 jpc_crgcomp_t *comp;
1237 1425
1238 /* Eliminate compiler warning about unused variables. */1426 JAS_UNUSED(cstate);
1239 (void)cstate;
1240 1427
1241 for (compno = 0, comp = crg->comps; compno < crg->numcomps; ++compno,1428 for (compno = 0, comp = crg->comps; compno < crg->numcomps; ++compno,
1242 ++comp) {1429 ++comp) {
@@ -1248,6 +1435,19 @@ static int jpc_crg_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 5 unmodified lines
1248 return 0;1435 return 0;
1249}1436}
1250 1437
1438static int jpc_crg_dumpparms(jpc_ms_t *ms)
1439{
1440 jpc_crg_t *crg = &ms->parms.crg;
1441 int compno;
1442 jpc_crgcomp_t *comp;
1443 for (compno = 0, comp = crg->comps; compno < crg->numcomps; ++compno,
1444 ++comp) {
1445 jas_logprintf("hoff[%d] = %"PRIuFAST16"; voff[%d] = %"PRIuFAST16"\n",
1446 compno, comp->hoff, compno, comp->voff);
1447 }
1448 return 0;
1449}
1450
1251/******************************************************************************\1451/******************************************************************************\
1252* Operations for COM marker segment.1452* Operations for COM marker segment.
1253\******************************************************************************/1453\******************************************************************************/
@@ -1264,8 +1464,7 @@ static int jpc_com_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in · 10 unmodified lines
1264{1464{
1265 jpc_com_t *com = &ms->parms.com;1465 jpc_com_t *com = &ms->parms.com;
1266 1466
1267 /* Eliminate compiler warning about unused variables. */1467 JAS_UNUSED(cstate);
1268 (void)cstate;
1269 1468
1270 if (jpc_getuint16(in, &com->regid)) {1469 if (jpc_getuint16(in, &com->regid)) {
1271 return -1;1470 return -1;
@@ -1288,8 +1487,7 @@ static int jpc_com_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 16 unmodified lines
1288{1487{
1289 jpc_com_t *com = &ms->parms.com;1488 jpc_com_t *com = &ms->parms.com;
1290 1489
1291 /* Eliminate compiler warning about unused variables. */1490 JAS_UNUSED(cstate);
1292 (void)cstate;
1293 1491
1294 if (jpc_putuint16(out, com->regid)) {1492 if (jpc_putuint16(out, com->regid)) {
1295 return -1;1493 return -1;
@@ -1300,6 +1498,29 @@ static int jpc_com_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou · 4 unmodified lines
1300 return 0;1498 return 0;
1301}1499}
1302 1500
1501static int jpc_com_dumpparms(jpc_ms_t *ms)
1502{
1503 jpc_com_t *com = &ms->parms.com;
1504 unsigned int i;
1505 int printable;
1506 jas_logprintf("regid = %"PRIuFAST16";\n", com->regid);
1507 printable = 1;
1508 for (i = 0; i < com->len; ++i) {
1509 if (!isprint(com->data[i])) {
1510 printable = 0;
1511 break;
1512 }
1513 }
1514 if (printable) {
1515 jas_logprintf("data = %.*s\n", com->len, com->data);
1516/* FIXME: print the data
1517 fwrite(com->data, sizeof(char), com->len, out);
1518 jas_logprintf("\n");
1519*/
1520 }
1521 return 0;
1522}
1523
1303/******************************************************************************\1524/******************************************************************************\
1304* Operations for unknown types of marker segments.1525* Operations for unknown types of marker segments.
1305\******************************************************************************/1526\******************************************************************************/
@@ -1318,8 +1539,7 @@ static int jpc_unk_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in · 12 unmodified lines
1318 1539
1319 unk->data = 0;1540 unk->data = 0;
1320 1541
1321 /* Eliminate compiler warning about unused variables. */1542 JAS_UNUSED(cstate);
1322 (void)cstate;
1323 1543
1324 if (ms->len > 0) {1544 if (ms->len > 0) {
1325 if (!(unk->data = jas_alloc2(ms->len, sizeof(unsigned char)))) {1545 if (!(unk->data = jas_alloc2(ms->len, sizeof(unsigned char)))) {
@@ -1339,16 +1559,25 @@ static int jpc_unk_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in · 13 unmodified lines
1339 1559
1340static int jpc_unk_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)1560static int jpc_unk_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
1341{1561{
1342 /* Eliminate compiler warning about unused variables. */1562 JAS_UNUSED(cstate);
1343 USED(cstate);1563 JAS_UNUSED(ms);
1344 USED(ms);1564 JAS_UNUSED(out);
1345 USED(out);
1346 1565
1347 /* If this function is called, we are trying to write an unsupported1566 /* If this function is called, we are trying to write an unsupported
1348 type of marker segment. Return with an error indication. */1567 type of marker segment. Return with an error indication. */
1349 return -1;1568 return -1;
1350}1569}
1351 1570
1571static int jpc_unk_dumpparms(jpc_ms_t *ms)
1572{
1573 unsigned int i;
1574 jpc_unk_t *unk = &ms->parms.unk;
1575 for (i = 0; i < unk->len; ++i) {
1576 jas_logprintf("%02x ", unk->data[i]);
1577 }
1578 return 0;
1579}
1580
1352/******************************************************************************\1581/******************************************************************************\
1353* Primitive I/O operations.1582* Primitive I/O operations.
1354\******************************************************************************/1583\******************************************************************************/
@@ -1430,6 +1659,12 @@ int jpc_validate(jas_stream_t *in) · 75 unmodified lines
1430{1659{
1431 unsigned char buf[2];1660 unsigned char buf[2];
1432 1661
1662 /*
1663 Note: The validation operation does not require the initialization of the
1664 JPC codec. So, jpc_init is not called here.
1665 jpc_init();
1666 */
1667
1433 assert(JAS_STREAM_MAXPUTBACK >= 2);1668 assert(JAS_STREAM_MAXPUTBACK >= 2);
1434 1669
1435 if (jas_stream_peek(in, buf, sizeof(buf)) != sizeof(buf))1670 if (jas_stream_peek(in, buf, sizeof(buf)) != sizeof(buf))
jpc_cs.h+6−0
@@ -726,6 +726,9 @@ typedef struct jpc_msops_s { · 725 unmodified lines
726 /* Put the marker segment parameters to a stream. */726 /* Put the marker segment parameters to a stream. */
727 int (*putparms)(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);727 int (*putparms)(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
728 728
729 /* Dump the marker segment parameters (for debugging). */
730 int (*dumpparms)(jpc_ms_t *ms);
731
729} jpc_msops_t;732} jpc_msops_t;
730 733
731/******************************************************************************\734/******************************************************************************\
@@ -771,6 +774,9 @@ int jpc_getdata(jas_stream_t *in, jas_stream_t *out, long n); · 39 unmodified lines
771/* Copy code stream data from one stream to another. */774/* Copy code stream data from one stream to another. */
772int jpc_putdata(jas_stream_t *out, jas_stream_t *in, long n);775int jpc_putdata(jas_stream_t *out, jas_stream_t *in, long n);
773 776
777/* Dump a marker segment (for debugging). */
778void jpc_ms_dump(jpc_ms_t *ms);
779
774/* Read a 8-bit unsigned integer from a stream. */780/* Read a 8-bit unsigned integer from a stream. */
775int jpc_getuint8(jas_stream_t *in, uint_fast8_t *val);781int jpc_getuint8(jas_stream_t *in, uint_fast8_t *val);
776 782
jpc_dec.c+415−112
@@ -78,8 +78,10 @@ · 77 unmodified lines
78#include "jpc_t1dec.h"78#include "jpc_t1dec.h"
79#include "jpc_math.h"79#include "jpc_math.h"
80 80
81#include "jasper/jas_init.h"
81#include "jasper/jas_types.h"82#include "jasper/jas_types.h"
82#include "jasper/jas_math.h"83#include "jasper/jas_math.h"
84#include "jasper/jas_tvp.h"
83#include "jasper/jas_malloc.h"85#include "jasper/jas_malloc.h"
84#include "jasper/jas_debug.h"86#include "jasper/jas_debug.h"
85 87
@@ -131,6 +133,8 @@ typedef struct { · 45 unmodified lines
131* Local function prototypes.133* Local function prototypes.
132\******************************************************************************/134\******************************************************************************/
133 135
136static int jpc_dec_dump(const jpc_dec_t *dec);
137
134static jpc_ppxstab_t *jpc_ppxstab_create(void);138static jpc_ppxstab_t *jpc_ppxstab_create(void);
135static void jpc_ppxstab_destroy(jpc_ppxstab_t *tab);139static void jpc_ppxstab_destroy(jpc_ppxstab_t *tab);
136static int jpc_ppxstab_grow(jpc_ppxstab_t *tab, unsigned maxents);140static int jpc_ppxstab_grow(jpc_ppxstab_t *tab, unsigned maxents);
@@ -197,6 +201,12 @@ static void jpc_dec_opts_destroy(jpc_dec_importopts_t *opts); · 60 unmodified lines
197 201
198static const jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id);202static const jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id);
199 203
204static void jpc_rlvl_init(jpc_dec_rlvl_t *rlvl);
205static void jpc_band_init(jpc_dec_band_t *band);
206static void jpc_prc_init(jpc_dec_prc_t *prc);
207static void jpc_cblk_init(jpc_dec_cblk_t *cblk);
208static void jpc_seglist_init(jpc_dec_seglist_t *seglist);
209
200/******************************************************************************\210/******************************************************************************\
201* Global data.211* Global data.
202\******************************************************************************/212\******************************************************************************/
@@ -236,13 +246,14 @@ jas_image_t *jpc_decode(jas_stream_t *in, const char *optstr) · 33 unmodified lines
236 246
237 dec = 0;247 dec = 0;
238 248
239 JAS_DBGLOG(100, ("jpc_decode(%p, \"%s\")\n", in, optstr));249 JAS_LOGDEBUGF(100, "jpc_decode(%p, \"%s\")\n", in, optstr);
240 250
241 if (!(opts = jpc_dec_opts_create(optstr))) {251 if (!(opts = jpc_dec_opts_create(optstr))) {
242 goto error;252 goto error;
243 }253 }
244 254
245 jpc_initluts();255 jpc_init();
256 //jpc_initluts();
246 257
247 if (!(dec = jpc_dec_create(opts, in))) {258 if (!(dec = jpc_dec_create(opts, in))) {
248 goto error;259 goto error;
@@ -290,11 +301,27 @@ error: · 41 unmodified lines
290 return 0;301 return 0;
291}302}
292 303
304typedef enum {
305 OPT_MAXLYRS,
306 OPT_MAXPKTS,
307 OPT_MAXSAMPLES,
308 OPT_DEBUG
309} optid_t;
310
311static const jas_taginfo_t decopts[] = {
312 {OPT_MAXLYRS, "maxlyrs"},
313 {OPT_MAXPKTS, "maxpkts"},
314 {OPT_MAXSAMPLES, "max_samples"},
315 {OPT_DEBUG, "debug"},
316 {-1, 0}
317};
318
293static jpc_dec_importopts_t *jpc_dec_opts_create(const char *optstr)319static jpc_dec_importopts_t *jpc_dec_opts_create(const char *optstr)
294{320{
295 jpc_dec_importopts_t *opts;321 jpc_dec_importopts_t *opts;
322 jas_tvparser_t *tvp;
323
296 324
297 USED(optstr);
298 if (!(opts = jas_malloc(sizeof(jpc_dec_importopts_t)))) {325 if (!(opts = jas_malloc(sizeof(jpc_dec_importopts_t)))) {
299 goto error;326 goto error;
300 }327 }
@@ -302,7 +329,35 @@ static jpc_dec_importopts_t *jpc_dec_opts_create(const char *optstr) · 1 unmodified line
302 opts->debug = 0;329 opts->debug = 0;
303 opts->maxlyrs = JPC_MAXLYRS;330 opts->maxlyrs = JPC_MAXLYRS;
304 opts->maxpkts = -1;331 opts->maxpkts = -1;
305 opts->max_samples = JAS_DEC_DEFAULT_MAX_SAMPLES;332 opts->max_samples = jas_get_dec_default_max_samples();
333
334 if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
335 goto error;
336 }
337
338 while (!jas_tvparser_next(tvp)) {
339 switch (jas_taginfo_nonull(jas_taginfos_lookup(decopts,
340 jas_tvparser_gettag(tvp)))->id) {
341 case OPT_MAXLYRS:
342 opts->maxlyrs = atoi(jas_tvparser_getval(tvp));
343 break;
344 case OPT_DEBUG:
345 opts->debug = atoi(jas_tvparser_getval(tvp));
346 break;
347 case OPT_MAXPKTS:
348 opts->maxpkts = atoi(jas_tvparser_getval(tvp));
349 break;
350 case OPT_MAXSAMPLES:
351 opts->max_samples = strtoull(jas_tvparser_getval(tvp), 0, 10);
352 break;
353 default:
354 jas_logwarnf("warning: ignoring invalid option %s\n",
355 jas_tvparser_gettag(tvp));
356 break;
357 }
358 }
359
360 jas_tvparser_destroy(tvp);
306 361
307 return opts;362 return opts;
308 363
@@ -353,7 +408,7 @@ static int jpc_dec_decode(jpc_dec_t *dec) · 44 unmodified lines
353 408
354 /* Get the next marker segment in the code stream. */409 /* Get the next marker segment in the code stream. */
355 if (!(ms = jpc_getms(dec->in, cstate))) {410 if (!(ms = jpc_getms(dec->in, cstate))) {
356 jas_eprintf("cannot get marker segment\n");411 jas_logerrorf("cannot get marker segment\n");
357 return -1;412 return -1;
358 }413 }
359 414
@@ -363,7 +418,7 @@ static int jpc_dec_decode(jpc_dec_t *dec) · 3 unmodified lines
363 /* Ensure that this type of marker segment is permitted418 /* Ensure that this type of marker segment is permitted
364 at this point in the code stream. */419 at this point in the code stream. */
365 if (!(dec->state & mstabent->validstates)) {420 if (!(dec->state & mstabent->validstates)) {
366 jas_eprintf("unexpected marker segment type\n");421 jas_logerrorf("unexpected marker segment type\n");
367 jpc_ms_destroy(ms);422 jpc_ms_destroy(ms);
368 return -1;423 return -1;
369 }424 }
@@ -407,15 +462,14 @@ static int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms) · 37 unmodified lines
407 cmpt->vsubstep = crg->comps[cmptno].voff;462 cmpt->vsubstep = crg->comps[cmptno].voff;
408 */463 */
409 /* suppress -Wunused-but-set-variable */464 /* suppress -Wunused-but-set-variable */
410 USED(crg);465 JAS_UNUSED(crg);
411 }466 }
412 return 0;467 return 0;
413}468}
414 469
415static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms)470static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms)
416{471{
417 /* Eliminate warnings about unused variables. */472 JAS_UNUSED(ms);
418 (void)ms;
419 473
420 /* We should expect to encounter a SIZ marker segment next. */474 /* We should expect to encounter a SIZ marker segment next. */
421 dec->state = JPC_MHSIZ;475 dec->state = JPC_MHSIZ;
@@ -478,7 +532,7 @@ static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms) · 56 unmodified lines
478 }532 }
479 533
480 if (sot->tileno >= dec->numtiles) {534 if (sot->tileno >= dec->numtiles) {
481 jas_eprintf("invalid tile number in SOT marker segment\n");535 jas_logerrorf("invalid tile number in SOT marker segment\n");
482 return -1;536 return -1;
483 }537 }
484 /* Set the current tile. */538 /* Set the current tile. */
@@ -529,8 +583,7 @@ static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms) · 44 unmodified lines
529 jpc_dec_tile_t *tile;583 jpc_dec_tile_t *tile;
530 int pos;584 int pos;
531 585
532 /* Eliminate compiler warnings about unused variables. */586 JAS_UNUSED(ms);
533 (void)ms;
534 587
535 if (!(tile = dec->curtile)) {588 if (!(tile = dec->curtile)) {
536 return -1;589 return -1;
@@ -564,18 +617,22 @@ static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms) · 27 unmodified lines
564 }617 }
565 }618 }
566 pos = jas_stream_tell(tile->pkthdrstream);619 pos = jas_stream_tell(tile->pkthdrstream);
567 jas_stream_seek(tile->pkthdrstream, 0, 2);620 jas_stream_seek(tile->pkthdrstream, 0, SEEK_END);
568 if (jpc_pptstabwrite(tile->pkthdrstream, tile->pptstab)) {621 if (jpc_pptstabwrite(tile->pkthdrstream, tile->pptstab)) {
569 return -1;622 return -1;
570 }623 }
571 jas_stream_seek(tile->pkthdrstream, pos, 0);624 jas_stream_seek(tile->pkthdrstream, pos, SEEK_SET);
572 jpc_ppxstab_destroy(tile->pptstab);625 jpc_ppxstab_destroy(tile->pptstab);
573 tile->pptstab = 0;626 tile->pptstab = 0;
574 }627 }
575 628
629 if (jas_get_debug_level() >= 10) {
630 jpc_dec_dump(dec);
631 }
632
576 if (jpc_dec_decodepkts(dec, (tile->pkthdrstream) ? tile->pkthdrstream :633 if (jpc_dec_decodepkts(dec, (tile->pkthdrstream) ? tile->pkthdrstream :
577 dec->in, dec->in)) {634 dec->in, dec->in)) {
578 jas_eprintf("jpc_dec_decodepkts failed\n");635 jas_logerrorf("jpc_dec_decodepkts failed\n");
579 return -1;636 return -1;
580 }637 }
581 638
@@ -586,17 +643,17 @@ static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms) · 4 unmodified lines
586 curoff = jas_stream_getrwcount(dec->in);643 curoff = jas_stream_getrwcount(dec->in);
587 if (curoff < dec->curtileendoff) {644 if (curoff < dec->curtileendoff) {
588 n = dec->curtileendoff - curoff;645 n = dec->curtileendoff - curoff;
589 jas_eprintf("warning: ignoring trailing garbage (%lu bytes)\n",646 jas_logwarnf("warning: ignoring trailing garbage (%lu bytes)\n",
590 (unsigned long) n);647 (unsigned long) n);
591 648
592 while (n-- > 0) {649 while (n-- > 0) {
593 if (jas_stream_getc(dec->in) == EOF) {650 if (jas_stream_getc(dec->in) == EOF) {
594 jas_eprintf("read error\n");651 jas_logerrorf("read error\n");
595 return -1;652 return -1;
596 }653 }
597 }654 }
598 } else if (curoff > dec->curtileendoff) {655 } else if (curoff > dec->curtileendoff) {
599 jas_eprintf("warning: not enough tile data (%lu bytes)\n",656 jas_logwarnf("warning: not enough tile data (%lu bytes)\n",
600 (unsigned long) curoff - dec->curtileendoff);657 (unsigned long) curoff - dec->curtileendoff);
601 }658 }
602 659
@@ -653,6 +710,11 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 50 unmodified lines
653 uint_fast32_t tmpyend;710 uint_fast32_t tmpyend;
654 jpc_tsfb_band_t bnds[JPC_MAXBANDS];711 jpc_tsfb_band_t bnds[JPC_MAXBANDS];
655 jpc_pchg_t *pchg;712 jpc_pchg_t *pchg;
713 int retval = 0;
714
715 if (jas_get_debug_level() >= 1) {
716 jas_logerrorf("jpc_dec_tileinit called\n");
717 }
656 718
657 const jpc_dec_cp_t *cp = tile->cp;719 const jpc_dec_cp_t *cp = tile->cp;
658 tile->realmode = 0;720 tile->realmode = 0;
@@ -665,27 +727,37 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 6 unmodified lines
665 for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <727 for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
666 dec->numcomps; ++compno, ++tcomp, ++cmpt) {728 dec->numcomps; ++compno, ++tcomp, ++cmpt) {
667 const jpc_dec_ccp_t *ccp = &tile->cp->ccps[compno];729 const jpc_dec_ccp_t *ccp = &tile->cp->ccps[compno];
730 if (jas_get_debug_level() >= 10) {
731 jas_logdebugf(10, "[compno %d]\n", compno);
732 }
668 if (ccp->qmfbid == JPC_COX_INS) {733 if (ccp->qmfbid == JPC_COX_INS) {
669 tile->realmode = 1;734 tile->realmode = 1;
670 }735 }
671 tcomp->numrlvls = ccp->numrlvls;736 tcomp->numrlvls = ccp->numrlvls;
672 if (!(tcomp->rlvls = jas_alloc2(tcomp->numrlvls,737 if (!(tcomp->rlvls = jas_alloc2(tcomp->numrlvls,
673 sizeof(jpc_dec_rlvl_t)))) {738 sizeof(jpc_dec_rlvl_t)))) {
674 return -1;739 retval = -1;
740 goto done;
675 }741 }
676 for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;742 for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
677 ++rlvlno, ++rlvl) {743 ++rlvlno, ++rlvl) {
744#if 0
678 rlvl->bands = NULL;745 rlvl->bands = NULL;
746#else
747 jpc_rlvl_init(rlvl);
748#endif
679 }749 }
680 if (!(tcomp->data = jas_seq2d_create(JPC_CEILDIV(tile->xstart,750 if (!(tcomp->data = jas_seq2d_create(JPC_CEILDIV(tile->xstart,
681 cmpt->hstep), JPC_CEILDIV(tile->ystart, cmpt->vstep),751 cmpt->hstep), JPC_CEILDIV(tile->ystart, cmpt->vstep),
682 JPC_CEILDIV(tile->xend, cmpt->hstep), JPC_CEILDIV(tile->yend,752 JPC_CEILDIV(tile->xend, cmpt->hstep), JPC_CEILDIV(tile->yend,
683 cmpt->vstep)))) {753 cmpt->vstep)))) {
684 return -1;754 retval = -1;
755 goto done;
685 }756 }
686 if (!(tcomp->tsfb = jpc_cod_gettsfb(ccp->qmfbid,757 if (!(tcomp->tsfb = jpc_cod_gettsfb(ccp->qmfbid,
687 tcomp->numrlvls - 1))) {758 tcomp->numrlvls - 1))) {
688 return -1;759 retval = -1;
760 goto done;
689 }761 }
690 {762 {
691 jpc_tsfb_getbands(tcomp->tsfb, jas_seq2d_xstart(tcomp->data),763 jpc_tsfb_getbands(tcomp->tsfb, jas_seq2d_xstart(tcomp->data),
@@ -719,6 +791,16 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 27 unmodified lines
719 rlvl->prcheightexpn;791 rlvl->prcheightexpn;
720 rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs;792 rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs;
721 793
794 if (jas_get_debug_level() >= 10) {
795 jas_logdebugf(10,
796 "[compno %d rlvlno %d]: xstart %d ystart %d "
797 "xend %d yend %d prcwidthexpn %d prcheightexpn %d "
798 "numhprcs %d numvprcs %d numprcs %d\n",
799 compno, rlvlno, rlvl->xstart, rlvl->ystart, rlvl->xend,
800 rlvl->yend, rlvl->prcwidthexpn, rlvl->prcheightexpn,
801 rlvl->numhprcs, rlvl->numvprcs, rlvl->numprcs);
802 }
803
722 if (rlvl->numprcs >= 64 * 1024) {804 if (rlvl->numprcs >= 64 * 1024) {
723 /* avoid out-of-memory due to805 /* avoid out-of-memory due to
724 malicious file; this limit is806 malicious file; this limit is
@@ -747,7 +829,8 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 22 unmodified lines
747 if (rlvl->prcwidthexpn < 1 || rlvl->prcheightexpn < 1) {829 if (rlvl->prcwidthexpn < 1 || rlvl->prcheightexpn < 1) {
748 /* the control block width/height offset830 /* the control block width/height offset
749 exponent must not be negative */831 exponent must not be negative */
750 return -1;832 retval = -1;
833 goto done;
751 }834 }
752 rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1;835 rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1;
753 rlvl->cbgheightexpn = rlvl->prcheightexpn - 1;836 rlvl->cbgheightexpn = rlvl->prcheightexpn - 1;
@@ -760,15 +843,26 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 6 unmodified lines
760 rlvl->numbands = (!rlvlno) ? 1 : 3;843 rlvl->numbands = (!rlvlno) ? 1 : 3;
761 if (!(rlvl->bands = jas_alloc2(rlvl->numbands,844 if (!(rlvl->bands = jas_alloc2(rlvl->numbands,
762 sizeof(jpc_dec_band_t)))) {845 sizeof(jpc_dec_band_t)))) {
763 return -1;846 retval = -1;
847 goto done;
764 }848 }
765 unsigned bandno;849 unsigned bandno;
850#if 1
851 for (bandno = 0, band = rlvl->bands;
852 bandno < rlvl->numbands; ++bandno, ++band) {
853 jpc_band_init(band);
854 }
855#endif
766 for (bandno = 0, band = rlvl->bands;856 for (bandno = 0, band = rlvl->bands;
767 bandno < rlvl->numbands; ++bandno, ++band) {857 bandno < rlvl->numbands; ++bandno, ++band) {
768 unsigned bndno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) +858 unsigned bndno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) +
769 bandno + 1);859 bandno + 1);
770 const jpc_tsfb_band_t *bnd = &bnds[bndno];860 const jpc_tsfb_band_t *bnd = &bnds[bndno];
771 861
862 if (jas_get_debug_level() >= 10) {
863 jas_logdebugf(10, "[compno %d rlvlno %d bandno %d]\n", compno, rlvlno, bandno);
864 }
865
772 band->orient = bnd->orient;866 band->orient = bnd->orient;
773 band->stepsize = ccp->stepsizes[bndno];867 band->stepsize = ccp->stepsizes[bndno];
774 band->analgain = JPC_NOMINALGAIN(ccp->qmfbid,868 band->analgain = JPC_NOMINALGAIN(ccp->qmfbid,
@@ -785,11 +879,13 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 10 unmodified lines
785 continue;879 continue;
786 }880 }
787 if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) {881 if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) {
788 return -1;882 retval = -1;
883 goto done;
789 }884 }
790 if (jas_seq2d_bindsub(band->data, tcomp->data, bnd->locxstart,885 if (jas_seq2d_bindsub(band->data, tcomp->data, bnd->locxstart,
791 bnd->locystart, bnd->locxend, bnd->locyend)) {886 bnd->locystart, bnd->locxend, bnd->locyend)) {
792 return -1;887 retval = -1;
888 goto done;
793 }889 }
794 jas_seq2d_setshift(band->data, bnd->xstart, bnd->ystart);890 jas_seq2d_setshift(band->data, bnd->xstart, bnd->ystart);
795 891
@@ -797,14 +893,25 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 1 unmodified line
797 893
798 if (!(band->prcs = jas_alloc2(rlvl->numprcs,894 if (!(band->prcs = jas_alloc2(rlvl->numprcs,
799 sizeof(jpc_dec_prc_t)))) {895 sizeof(jpc_dec_prc_t)))) {
800 return -1;896 retval = -1;
897 goto done;
801 }898 }
802 899
803/************************************************/900/************************************************/
804 cbgxstart = tlcbgxstart;901 cbgxstart = tlcbgxstart;
805 cbgystart = tlcbgystart;902 cbgystart = tlcbgystart;
806 unsigned prccnt; for (prccnt = rlvl->numprcs, prc = band->prcs;903 unsigned prccnt;
904#if 1
905 for (prccnt = rlvl->numprcs, prc = band->prcs;
807 prccnt > 0; --prccnt, ++prc) {906 prccnt > 0; --prccnt, ++prc) {
907 jpc_prc_init(prc);
908 }
909#endif
910 for (prccnt = rlvl->numprcs, prc = band->prcs;
911 prccnt > 0; --prccnt, ++prc) {
912 if (jas_get_debug_level() >= 10) {
913 jas_logdebugf(10, "[compno %d rlvlno %d bandno %d prccnt %d]\n", compno, rlvlno, bandno, prccnt);
914 }
808 cbgxend = cbgxstart + (1 << rlvl->cbgwidthexpn);915 cbgxend = cbgxstart + (1 << rlvl->cbgwidthexpn);
809 cbgyend = cbgystart + (1 << rlvl->cbgheightexpn);916 cbgyend = cbgystart + (1 << rlvl->cbgheightexpn);
810 prc->xstart = JAS_MAX(cbgxstart, JAS_CAST(uint_fast32_t,917 prc->xstart = JAS_MAX(cbgxstart, JAS_CAST(uint_fast32_t,
@@ -831,24 +938,43 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 20 unmodified lines
831 prc->numcblks = prc->numhcblks * prc->numvcblks;938 prc->numcblks = prc->numhcblks * prc->numvcblks;
832 assert(prc->numcblks > 0);939 assert(prc->numcblks > 0);
833 940
941 if (jas_get_debug_level() >= 10) {
942 jas_logdebugf(10, "[compno %d rlvlno %d bandno %d prccnt %d]: "
943 "numhcblks %d numvcblks %d numcblks %d\n",
944 compno, rlvlno, bandno, prccnt, prc->numhcblks, prc->numvcblks,
945 prc->numcblks);
946 }
947
834 if (!(prc->incltagtree = jpc_tagtree_create(948 if (!(prc->incltagtree = jpc_tagtree_create(
835 prc->numhcblks, prc->numvcblks))) {949 prc->numhcblks, prc->numvcblks))) {
836 return -1;950 retval = -1;
951 goto done;
837 }952 }
838 if (!(prc->numimsbstagtree = jpc_tagtree_create(953 if (!(prc->numimsbstagtree = jpc_tagtree_create(
839 prc->numhcblks, prc->numvcblks))) {954 prc->numhcblks, prc->numvcblks))) {
840 return -1;955 retval = -1;
956 goto done;
841 }957 }
842 if (!(prc->cblks = jas_alloc2(prc->numcblks,958 if (!(prc->cblks = jas_alloc2(prc->numcblks,
843 sizeof(jpc_dec_cblk_t)))) {959 sizeof(jpc_dec_cblk_t)))) {
844 return -1;960 retval = -1;
961 goto done;
845 }962 }
846 963
847 cblkxstart = cbgxstart;964 cblkxstart = cbgxstart;
848 cblkystart = cbgystart;965 cblkystart = cbgystart;
849 unsigned cblkcnt;966 unsigned cblkcnt;
967#if 1
968 for (cblkcnt = prc->numcblks, cblk = prc->cblks;
969 cblkcnt > 0; ++cblk, --cblkcnt) {
970 jpc_cblk_init(cblk);
971 }
972#endif
850 for (cblkcnt = prc->numcblks, cblk = prc->cblks;973 for (cblkcnt = prc->numcblks, cblk = prc->cblks;
851 cblkcnt > 0;) {974 cblkcnt > 0;) {
975 if (jas_get_debug_level() >= 10000) {
976 jas_logdebugf(10000, "[compno %d rlvlno %d bandno %d prcno %d cblkcnt %d]\n", compno, rlvlno, bandno, prccnt, cblkcnt);
977 }
852 cblkxend = cblkxstart + (1 << rlvl->cblkwidthexpn);978 cblkxend = cblkxstart + (1 << rlvl->cblkwidthexpn);
853 cblkyend = cblkystart + (1 << rlvl->cblkheightexpn);979 cblkyend = cblkystart + (1 << rlvl->cblkheightexpn);
854 tmpxstart = JAS_MAX(cblkxstart, prc->xstart);980 tmpxstart = JAS_MAX(cblkxstart, prc->xstart);
@@ -865,11 +991,13 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 10 unmodified lines
865 cblk->numlenbits = 3;991 cblk->numlenbits = 3;
866 if (!(cblk->data = jas_seq2d_create(0, 0, 0,992 if (!(cblk->data = jas_seq2d_create(0, 0, 0,
867 0))) {993 0))) {
868 return -1;994 retval = -1;
995 goto done;
869 }996 }
870 if (jas_seq2d_bindsub(cblk->data, band->data,997 if (jas_seq2d_bindsub(cblk->data, band->data,
871 tmpxstart, tmpystart, tmpxend, tmpyend)) {998 tmpxstart, tmpystart, tmpxend, tmpyend)) {
872 return -1;999 retval = -1;
1000 goto done;
873 }1001 }
874 ++cblk;1002 ++cblk;
875 --cblkcnt;1003 --cblkcnt;
@@ -899,7 +1027,8 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 23 unmodified lines
899 }1027 }
900 1028
901 if (!(tile->pi = jpc_dec_pi_create(dec, tile))) {1029 if (!(tile->pi = jpc_dec_pi_create(dec, tile))) {
902 return -1;1030 retval = -1;
1031 goto done;
903 }1032 }
904 1033
905 for (unsigned pchgno = 0; pchgno < jpc_pchglist_numpchgs(tile->cp->pchglist);1034 for (unsigned pchgno = 0; pchgno < jpc_pchglist_numpchgs(tile->cp->pchglist);
@@ -910,7 +1039,13 @@ static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 4 unmodified lines
910 }1039 }
911 jpc_pi_init(tile->pi);1040 jpc_pi_init(tile->pi);
912 1041
913 return 0;1042done:
1043
1044 if (jas_get_debug_level() >= 1) {
1045 jas_logdebugf(1, "jpc_dec_tileinit returning %d\n", retval);
1046 }
1047
1048 return retval;
914}1049}
915 1050
916static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile)1051static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile)
@@ -920,61 +1055,64 @@ static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 3 unmodified lines
920 jpc_dec_seg_t *seg;1055 jpc_dec_seg_t *seg;
921 jpc_dec_cblk_t *cblk;1056 jpc_dec_cblk_t *cblk;
922 1057
923 if (tile->tcomps) {1058 if (jas_get_debug_level() >= 1) {
1059 jas_logdebugf(1, "jpc_dec_tilefini called\n");
1060 }
924 1061
1062 if (tile->tcomps) {
925 unsigned compno;1063 unsigned compno;
926 for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;1064 for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
927 ++compno, ++tcomp) {1065 ++compno, ++tcomp) {
928 const jpc_dec_rlvl_t *rlvl;1066 if (tcomp->rlvls) {
929 for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;1067 const jpc_dec_rlvl_t *rlvl;
930 ++rlvlno, ++rlvl) {1068 for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
931 if (!rlvl->bands) {1069 ++rlvlno, ++rlvl) {
932 continue;1070 if (!rlvl->bands) {
933 }1071 continue;
934 unsigned bandno;1072 }
935 const jpc_dec_band_t *band;1073 unsigned bandno;
936 for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;1074 const jpc_dec_band_t *band;
937 ++bandno, ++band) {1075 for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
938 if (band->prcs) {1076 ++bandno, ++band) {
939 unsigned prcno;1077 if (band->prcs) {
940 const jpc_dec_prc_t *prc;1078 unsigned prcno;
941 for (prcno = 0, prc = band->prcs; prcno <1079 const jpc_dec_prc_t *prc;
942 rlvl->numprcs; ++prcno, ++prc) {1080 for (prcno = 0, prc = band->prcs; prcno <
943 if (!prc->cblks) {1081 rlvl->numprcs; ++prcno, ++prc) {
944 continue;1082 if (prc->cblks) {
945 }1083 unsigned cblkno;
946 unsigned cblkno;1084 for (cblkno = 0, cblk = prc->cblks; cblkno <
947 for (cblkno = 0, cblk = prc->cblks; cblkno <1085 prc->numcblks; ++cblkno, ++cblk) {
948 prc->numcblks; ++cblkno, ++cblk) {1086 while (cblk->segs.head) {
949 1087 seg = cblk->segs.head;
950 while (cblk->segs.head) {1088 jpc_seglist_remove(&cblk->segs, seg);
951 seg = cblk->segs.head;1089 jpc_seg_destroy(seg);
952 jpc_seglist_remove(&cblk->segs, seg);1090 }
953 jpc_seg_destroy(seg);1091 if (cblk->data) {
1092 jas_matrix_destroy(cblk->data);
1093 }
1094 }
1095 jas_free(prc->cblks);
1096 }
1097 if (prc->incltagtree) {
1098 jpc_tagtree_destroy(prc->incltagtree);
1099 }
1100 if (prc->numimsbstagtree) {
1101 jpc_tagtree_destroy(prc->numimsbstagtree);
954 }1102 }
955 jas_matrix_destroy(cblk->data);
956 }
957 if (prc->incltagtree) {
958 jpc_tagtree_destroy(prc->incltagtree);
959 }
960 if (prc->numimsbstagtree) {
961 jpc_tagtree_destroy(prc->numimsbstagtree);
962 }
963 if (prc->cblks) {
964 jas_free(prc->cblks);
965 }1103 }
966 }1104 }
1105 if (band->data) {
1106 jas_matrix_destroy(band->data);
1107 }
1108 if (band->prcs) {
1109 jas_free(band->prcs);
1110 }
967 }1111 }
968 if (band->data) {1112 if (rlvl->bands) {
969 jas_matrix_destroy(band->data);1113 jas_free(rlvl->bands);
970 }
971 if (band->prcs) {
972 jas_free(band->prcs);
973 }1114 }
974 }1115 }
975 if (rlvl->bands) {
976 jas_free(rlvl->bands);
977 }
978 }1116 }
979 if (tcomp->rlvls) {1117 if (tcomp->rlvls) {
980 jas_free(tcomp->rlvls);1118 jas_free(tcomp->rlvls);
@@ -1020,7 +1158,7 @@ static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 39 unmodified lines
1020 int v;1158 int v;
1021 1159
1022 if (jpc_dec_decodecblks(dec, tile)) {1160 if (jpc_dec_decodecblks(dec, tile)) {
1023 jas_eprintf("jpc_dec_decodecblks failed\n");1161 jas_logerrorf("jpc_dec_decodecblks failed\n");
1024 return -1;1162 return -1;
1025 }1163 }
1026 1164
@@ -1065,11 +1203,11 @@ static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 38 unmodified lines
1065 switch (tile->cp->mctid) {1203 switch (tile->cp->mctid) {
1066 case JPC_MCT_RCT:1204 case JPC_MCT_RCT:
1067 if (dec->numcomps < 3) {1205 if (dec->numcomps < 3) {
1068 jas_eprintf("RCT requires at least three components\n");1206 jas_logerrorf("RCT requires at least three components\n");
1069 return -1;1207 return -1;
1070 }1208 }
1071 if (!jas_image_cmpt_domains_same(dec->image)) {1209 if (!jas_image_cmpt_domains_same(dec->image)) {
1072 jas_eprintf("RCT requires all components have the same domain\n");1210 jas_logerrorf("RCT requires all components have the same domain\n");
1073 return -1;1211 return -1;
1074 }1212 }
1075 jpc_irct(tile->tcomps[0].data, tile->tcomps[1].data,1213 jpc_irct(tile->tcomps[0].data, tile->tcomps[1].data,
@@ -1077,11 +1215,11 @@ static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 1 unmodified line
1077 break;1215 break;
1078 case JPC_MCT_ICT:1216 case JPC_MCT_ICT:
1079 if (dec->numcomps < 3) {1217 if (dec->numcomps < 3) {
1080 jas_eprintf("ICT requires at least three components\n");1218 jas_logerrorf("ICT requires at least three components\n");
1081 return -1;1219 return -1;
1082 }1220 }
1083 if (!jas_image_cmpt_domains_same(dec->image)) {1221 if (!jas_image_cmpt_domains_same(dec->image)) {
1084 jas_eprintf("RCT requires all components have the same domain\n");1222 jas_logerrorf("RCT requires all components have the same domain\n");
1085 return -1;1223 return -1;
1086 }1224 }
1087 jpc_iict(tile->tcomps[0].data, tile->tcomps[1].data,1225 jpc_iict(tile->tcomps[0].data, tile->tcomps[1].data,
@@ -1154,7 +1292,7 @@ static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile) · 66 unmodified lines
1154 JPC_CEILDIV(dec->xstart, cmpt->hstep), tcomp->ystart -1292 JPC_CEILDIV(dec->xstart, cmpt->hstep), tcomp->ystart -
1155 JPC_CEILDIV(dec->ystart, cmpt->vstep), jas_matrix_numcols(1293 JPC_CEILDIV(dec->ystart, cmpt->vstep), jas_matrix_numcols(
1156 tcomp->data), jas_matrix_numrows(tcomp->data), tcomp->data)) {1294 tcomp->data), jas_matrix_numrows(tcomp->data), tcomp->data)) {
1157 jas_eprintf("write component failed\n");1295 jas_logerrorf("write component failed\n");
1158 return -1;1296 return -1;
1159 }1297 }
1160 }1298 }
@@ -1166,8 +1304,7 @@ static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms) · 5 unmodified lines
1166{1304{
1167 jpc_dec_tile_t *tile;1305 jpc_dec_tile_t *tile;
1168 1306
1169 /* Eliminate compiler warnings about unused variables. */1307 JAS_UNUSED(ms);
1170 (void)ms;
1171 1308
1172 unsigned tileno;1309 unsigned tileno;
1173 for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno,1310 for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno,
@@ -1204,14 +1341,14 @@ static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms) · 30 unmodified lines
1204 size_t total_samples;1341 size_t total_samples;
1205 if (!jas_safe_size_mul(siz->width, siz->height, &total_samples) ||1342 if (!jas_safe_size_mul(siz->width, siz->height, &total_samples) ||
1206 (dec->max_samples > 0 && total_samples > dec->max_samples)) {1343 (dec->max_samples > 0 && total_samples > dec->max_samples)) {
1207 jas_eprintf("image too large\n");1344 jas_logerrorf("image too large\n");
1208 return -1;1345 return -1;
1209 }1346 }
1210 1347
1211 size_t tile_samples;1348 size_t tile_samples;
1212 if (!jas_safe_size_mul(siz->tilewidth, siz->tileheight, &tile_samples) ||1349 if (!jas_safe_size_mul(siz->tilewidth, siz->tileheight, &tile_samples) ||
1213 (dec->max_samples > 0 && tile_samples > dec->max_samples)) {1350 (dec->max_samples > 0 && tile_samples > dec->max_samples)) {
1214 jas_eprintf("tile too large\n");1351 jas_logerrorf("tile too large\n");
1215 return -1;1352 return -1;
1216 }1353 }
1217 1354
@@ -1248,18 +1385,22 @@ static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms) · 30 unmodified lines
1248 cmpt->hsubstep = 0;1385 cmpt->hsubstep = 0;
1249 cmpt->vsubstep = 0;1386 cmpt->vsubstep = 0;
1250 1387
1388 if (!cmpt->width || !cmpt->height) {
1389 jas_logerrorf("image component has no samples\n");
1390 return -1;
1391 }
1251 if (!jas_safe_size_mul(cmpt->width, cmpt->height, &num_samples_delta)) {1392 if (!jas_safe_size_mul(cmpt->width, cmpt->height, &num_samples_delta)) {
1252 jas_eprintf("image too large\n");1393 jas_logerrorf("image too large\n");
1253 return -1;1394 return -1;
1254 }1395 }
1255 if (!jas_safe_size_add(num_samples, num_samples_delta, &num_samples)) {1396 if (!jas_safe_size_add(num_samples, num_samples_delta, &num_samples)) {
1256 jas_eprintf("image too large\n");1397 jas_logerrorf("image too large\n");
1257 return -1;1398 return -1;
1258 }1399 }
1259 }1400 }
1260 1401
1261 if (dec->max_samples > 0 && num_samples > dec->max_samples) {1402 if (dec->max_samples > 0 && num_samples > dec->max_samples) {
1262 jas_eprintf("maximum number of samples exceeded (%zu > %zu)\n",1403 jas_logerrorf("maximum number of samples exceeded (%zu > %zu)\n",
1263 num_samples, dec->max_samples);1404 num_samples, dec->max_samples);
1264 return -1;1405 return -1;
1265 }1406 }
@@ -1287,8 +1428,8 @@ static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms) · 21 unmodified lines
1287 return -1;1428 return -1;
1288 }1429 }
1289 dec->numtiles = size;1430 dec->numtiles = size;
1290 JAS_DBGLOG(10, ("numtiles = %d; numhtiles = %d; numvtiles = %d;\n",1431 JAS_LOGDEBUGF(10, "numtiles = %d; numhtiles = %d; numvtiles = %d;\n",
1291 dec->numtiles, dec->numhtiles, dec->numvtiles));1432 dec->numtiles, dec->numhtiles, dec->numvtiles);
1292 if (!(dec->tiles = jas_alloc2(dec->numtiles, sizeof(jpc_dec_tile_t)))) {1433 if (!(dec->tiles = jas_alloc2(dec->numtiles, sizeof(jpc_dec_tile_t)))) {
1293 return -1;1434 return -1;
1294 }1435 }
@@ -1377,7 +1518,7 @@ static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms) · 82 unmodified lines
1377 jpc_dec_tile_t *tile;1518 jpc_dec_tile_t *tile;
1378 1519
1379 if (coc->compno >= dec->numcomps) {1520 if (coc->compno >= dec->numcomps) {
1380 jas_eprintf("invalid component number in COC marker segment\n");1521 jas_logerrorf("invalid component number in COC marker segment\n");
1381 return -1;1522 return -1;
1382 }1523 }
1383 switch (dec->state) {1524 switch (dec->state) {
@@ -1403,7 +1544,7 @@ static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms) · 19 unmodified lines
1403 jpc_dec_tile_t *tile;1544 jpc_dec_tile_t *tile;
1404 1545
1405 if (rgn->compno >= dec->numcomps) {1546 if (rgn->compno >= dec->numcomps) {
1406 jas_eprintf("invalid component number in RGN marker segment\n");1547 jas_logerrorf("invalid component number in RGN marker segment\n");
1407 return -1;1548 return -1;
1408 }1549 }
1409 switch (dec->state) {1550 switch (dec->state) {
@@ -1452,7 +1593,7 @@ static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms) · 42 unmodified lines
1452 jpc_dec_tile_t *tile;1593 jpc_dec_tile_t *tile;
1453 1594
1454 if (qcc->compno >= dec->numcomps) {1595 if (qcc->compno >= dec->numcomps) {
1455 jas_eprintf("invalid component number in QCC marker segment\n");1596 jas_logerrorf("invalid component number in QCC marker segment\n");
1456 return -1;1597 return -1;
1457 }1598 }
1458 switch (dec->state) {1599 switch (dec->state) {
@@ -1551,19 +1692,17 @@ static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms) · 92 unmodified lines
1551 1692
1552static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms)1693static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms)
1553{1694{
1554 /* Eliminate compiler warnings about unused variables. */1695 JAS_UNUSED(dec);
1555 USED(dec);1696 JAS_UNUSED(ms);
1556 USED(ms);
1557 1697
1558 return 0;1698 return 0;
1559}1699}
1560 1700
1561static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms)1701static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms)
1562{1702{
1563 /* Eliminate compiler warnings about unused variables. */1703 JAS_UNUSED(dec);
1564 USED(dec);
1565 1704
1566 jas_eprintf("warning: ignoring unknown marker segment (0x%x)\n",1705 jas_logwarnf("warning: ignoring unknown marker segment (0x%x)\n",
1567 ms->id);1706 ms->id);
1568 return 0;1707 return 0;
1569}1708}
@@ -1586,6 +1725,7 @@ static jpc_dec_cp_t *jpc_dec_cp_create(uint_fast16_t numcomps) · 16 unmodified lines
1586 cp->numlyrs = 0;1725 cp->numlyrs = 0;
1587 cp->mctid = 0;1726 cp->mctid = 0;
1588 cp->csty = 0;1727 cp->csty = 0;
1728 cp->pchglist = 0;
1589 if (!(cp->ccps = jas_alloc2(cp->numcomps, sizeof(jpc_dec_ccp_t)))) {1729 if (!(cp->ccps = jas_alloc2(cp->numcomps, sizeof(jpc_dec_ccp_t)))) {
1590 goto error;1730 goto error;
1591 }1731 }
@@ -1694,7 +1834,11 @@ static int calcstepsizes(uint_fast16_t refstepsize, unsigned numrlvls, · 102 unmodified lines
1694 mant = JPC_QCX_GETMANT(refstepsize);1834 mant = JPC_QCX_GETMANT(refstepsize);
1695 const unsigned numbands = 3 * numrlvls - 2;1835 const unsigned numbands = 3 * numrlvls - 2;
1696 for (unsigned bandno = 0; bandno < numbands; ++bandno) {1836 for (unsigned bandno = 0; bandno < numbands; ++bandno) {
1697//jas_eprintf("DEBUG %d %d %d %d %d\n", bandno, expn, numrlvls, bandno, ((numrlvls - 1) - (numrlvls - 1 - ((bandno > 0) ? ((bandno + 2) / 3) : (0)))));1837#if 0
1838 jas_eprintf("DEBUG %d %d %d %d %d\n", bandno, expn, numrlvls, bandno,
1839 ((numrlvls - 1) - (numrlvls - 1 - ((bandno > 0) ? ((bandno + 2) / 3)
1840 : (0)))));
1841#endif
1698 const unsigned r = (bandno + 2) / 3;1842 const unsigned r = (bandno + 2) / 3;
1699 const unsigned nb = (r == 0) ? (numrlvls - 1) - r : (numrlvls - 1) - r + 1;1843 const unsigned nb = (r == 0) ? (numrlvls - 1) - r : (numrlvls - 1) - r + 1;
1700 uint_fast16_t e = expn - (numrlvls - 1) + nb;1844 uint_fast16_t e = expn - (numrlvls - 1) + nb;
@@ -1758,8 +1902,7 @@ static int jpc_dec_cp_setfromcox(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp, · 57 unmodified lines
1758{1902{
1759 int rlvlno;1903 int rlvlno;
1760 1904
1761 /* Eliminate compiler warnings about unused variables. */1905 JAS_UNUSED(cp);
1762 USED(cp);
1763 1906
1764 if ((flags & JPC_COC) || !(ccp->flags & JPC_COC)) {1907 if ((flags & JPC_COC) || !(ccp->flags & JPC_COC)) {
1765 ccp->numrlvls = compparms->numdlvls + 1;1908 ccp->numrlvls = compparms->numdlvls + 1;
@@ -1803,8 +1946,7 @@ static int jpc_dec_cp_setfromqcx(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp, · 37 unmodified lines
1803{1946{
1804 int bandno;1947 int bandno;
1805 1948
1806 /* Eliminate compiler warnings about unused variables. */1949 JAS_UNUSED(cp);
1807 USED(cp);
1808 1950
1809 /* Sanity check to prevent buffer overflow */1951 /* Sanity check to prevent buffer overflow */
1810 if (compparms->numstepsizes > (3 * JPC_MAXRLVLS + 1)) {1952 if (compparms->numstepsizes > (3 * JPC_MAXRLVLS + 1)) {
@@ -1886,7 +2028,15 @@ static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize) · 75 unmodified lines
1886 // a reconstruction parameter defined in E 1.1.2 of the ISO/IEC 15444-12028 // a reconstruction parameter defined in E 1.1.2 of the ISO/IEC 15444-1
1887 jpc_fix_t recparam = JPC_FIX_HALF;2029 jpc_fix_t recparam = JPC_FIX_HALF;
1888 2030
1889 assert(absstepsize >= 0);2031 // Note:
2032 // Should anything special be done to handle the error case of
2033 // absstepsize < 0 (which can arise due to numerical overflow).
2034 // Using an assert is not appropriate, since this results in program
2035 // termination when this type of error occurs.
2036 // Simply allowing a decoded image with very high distortion would appear
2037 // to be consistent with the policy adopted elsewhere in the codec.
2038 // assert(absstepsize >= 0);
2039
1890 if (absstepsize == jpc_inttofix(1)) {2040 if (absstepsize == jpc_inttofix(1)) {
1891 return;2041 return;
1892 }2042 }
@@ -1920,7 +2070,7 @@ static void jpc_undo_roi(jas_matrix_t *x, int roishift, int bgshift, unsigned nu · 27 unmodified lines
1920 if (roishift < 0) {2070 if (roishift < 0) {
1921 /* We could instead return an error here. */2071 /* We could instead return an error here. */
1922 /* I do not think it matters much. */2072 /* I do not think it matters much. */
1923 jas_eprintf("warning: forcing negative ROI shift to zero "2073 jas_logwarnf("warning: forcing negative ROI shift to zero "
1924 "(bitstream is probably corrupt)\n");2074 "(bitstream is probably corrupt)\n");
1925 roishift = 0;2075 roishift = 0;
1926 }2076 }
@@ -1953,7 +2103,7 @@ static void jpc_undo_roi(jas_matrix_t *x, int roishift, int bgshift, unsigned nu · 26 unmodified lines
1953 Here we ensure that any such bits are masked off. */2103 Here we ensure that any such bits are masked off. */
1954 if (mag & (~mask)) {2104 if (mag & (~mask)) {
1955 if (!warn) {2105 if (!warn) {
1956 jas_eprintf("warning: possibly corrupt code stream\n");2106 jas_logwarnf("warning: possibly corrupt code stream\n");
1957 warn = true;2107 warn = true;
1958 }2108 }
1959 mag &= mask;2109 mag &= mask;
@@ -1992,7 +2142,7 @@ static jpc_dec_t *jpc_dec_create(jpc_dec_importopts_t *impopts, jas_stream_t *in · 32 unmodified lines
1992 dec->cp = 0;2142 dec->cp = 0;
1993 dec->maxlyrs = impopts->maxlyrs;2143 dec->maxlyrs = impopts->maxlyrs;
1994 dec->maxpkts = impopts->maxpkts;2144 dec->maxpkts = impopts->maxpkts;
1995dec->numpkts = 0;2145 dec->numpkts = 0;
1996 dec->ppmseqno = 0;2146 dec->ppmseqno = 0;
1997 dec->state = 0;2147 dec->state = 0;
1998 dec->cmpts = 0;2148 dec->cmpts = 0;
@@ -2001,6 +2151,10 @@ dec->numpkts = 0; · 2 unmodified lines
2001 dec->curtileendoff = 0;2151 dec->curtileendoff = 0;
2002 dec->max_samples = impopts->max_samples;2152 dec->max_samples = impopts->max_samples;
2003 2153
2154 if (jas_get_debug_level() >= 1) {
2155 jas_logdebugf(1, "debug %d\n", jas_get_debug_level());
2156 }
2157
2004 return dec;2158 return dec;
2005}2159}
2006 2160
@@ -2119,6 +2273,83 @@ void jpc_seg_destroy(jpc_dec_seg_t *seg) · 112 unmodified lines
2119 jas_free(seg);2273 jas_free(seg);
2120}2274}
2121 2275
2276static int jpc_dec_dump(const jpc_dec_t *dec)
2277{
2278 assert(!dec->numtiles || dec->tiles);
2279 unsigned tileno;
2280 const jpc_dec_tile_t *tile;
2281 for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles;
2282 ++tileno, ++tile) {
2283 assert(!dec->numcomps || tile->tcomps);
2284 unsigned compno;
2285 const jpc_dec_tcomp_t *tcomp;
2286 for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
2287 ++compno, ++tcomp) {
2288 unsigned rlvlno;
2289 const jpc_dec_rlvl_t *rlvl;
2290 for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno <
2291 tcomp->numrlvls; ++rlvlno, ++rlvl) {
2292 jas_logprintf("RESOLUTION LEVEL %d\n", rlvlno);
2293 jas_logprintf("xs = %"PRIuFAST32", ys = %"PRIuFAST32", xe = %"PRIuFAST32", ye = %"PRIuFAST32", w = %"PRIuFAST32", h = %"PRIuFAST32"\n",
2294 rlvl->xstart, rlvl->ystart, rlvl->xend, rlvl->yend,
2295 rlvl->xend - rlvl->xstart, rlvl->yend - rlvl->ystart);
2296 assert(!rlvl->numbands || rlvl->bands);
2297 unsigned bandno;
2298 const jpc_dec_band_t *band;
2299 for (bandno = 0, band = rlvl->bands;
2300 bandno < rlvl->numbands; ++bandno, ++band) {
2301 jas_logprintf("BAND %d\n", bandno);
2302 if (!band->data) {
2303 jas_logprintf("band has no data (null pointer)\n");
2304 assert(!band->prcs);
2305 continue;
2306 }
2307 jas_logprintf("xs = %"PRIjas_seqent", ys = %"PRIjas_seqent", xe = %"PRIjas_seqent", ye = %"PRIjas_seqent", w = %"PRIjas_seqent", h = %"PRIjas_seqent"\n",
2308 jas_seq2d_xstart(band->data),
2309 jas_seq2d_ystart(band->data),
2310 jas_seq2d_xend(band->data),
2311 jas_seq2d_yend(band->data),
2312 jas_seq2d_xend(band->data) -
2313 jas_seq2d_xstart(band->data),
2314 jas_seq2d_yend(band->data) -
2315 jas_seq2d_ystart(band->data));
2316 assert(!rlvl->numprcs || band->prcs);
2317 unsigned prcno;
2318 const jpc_dec_prc_t *prc;
2319 for (prcno = 0, prc = band->prcs;
2320 prcno < rlvl->numprcs; ++prcno,
2321 ++prc) {
2322 jas_logprintf("CODE BLOCK GROUP %d\n", prcno);
2323 jas_logprintf("xs = %"PRIuFAST32", ys = %"PRIuFAST32", xe = %"PRIuFAST32", ye = %"PRIuFAST32", w = %"PRIuFAST32", h = %"PRIuFAST32"\n",
2324 prc->xstart, prc->ystart, prc->xend, prc->yend,
2325 prc->xend - prc->xstart, prc->yend - prc->ystart);
2326 assert(!prc->numcblks || prc->cblks);
2327 unsigned cblkno;
2328 const jpc_dec_cblk_t *cblk;
2329 for (cblkno = 0, cblk =
2330 prc->cblks; cblkno <
2331 prc->numcblks; ++cblkno,
2332 ++cblk) {
2333 jas_logprintf("CODE BLOCK %d\n", cblkno);
2334 jas_logprintf("xs = %"PRIjas_seqent", ys = %"PRIjas_seqent", xe = %"PRIjas_seqent", ye = %"PRIjas_seqent", w = %"PRIjas_seqent", h = %"PRIjas_seqent"\n",
2335 jas_seq2d_xstart(cblk->data),
2336 jas_seq2d_ystart(cblk->data),
2337 jas_seq2d_xend(cblk->data),
2338 jas_seq2d_yend(cblk->data),
2339 jas_seq2d_xend(cblk->data) -
2340 jas_seq2d_xstart(cblk->data),
2341 jas_seq2d_yend(cblk->data) -
2342 jas_seq2d_ystart(cblk->data));
2343 }
2344 }
2345 }
2346 }
2347 }
2348 }
2349
2350 return 0;
2351}
2352
2122static jpc_streamlist_t *jpc_streamlist_create()2353static jpc_streamlist_t *jpc_streamlist_create()
2123{2354{
2124 jpc_streamlist_t *streamlist;2355 jpc_streamlist_t *streamlist;
@@ -2366,3 +2597,75 @@ static void jpc_ppxstabent_destroy(jpc_ppxstabent_t *ent) · 241 unmodified lines
2366 }2597 }
2367 jas_free(ent);2598 jas_free(ent);
2368}2599}
2600
2601static void jpc_cblk_init(jpc_dec_cblk_t *cblk)
2602{
2603#if 1
2604 memset(cblk, 0, sizeof(jpc_dec_cblk_t));
2605 cblk->numpasses = 0;
2606 jpc_seglist_init(&cblk->segs);
2607 cblk->curseg = 0;
2608 cblk->numimsbs = 0;
2609 cblk->numlenbits = 0;
2610 cblk->firstpassno = 0;
2611 cblk->data = 0;
2612#endif
2613}
2614
2615static void jpc_prc_init(jpc_dec_prc_t *prc)
2616{
2617#if 1
2618 memset(prc, 0, sizeof(jpc_dec_prc_t));
2619 prc->xstart = 0;
2620 prc->ystart = 0;
2621 prc->xend = 0;
2622 prc->yend = 0;
2623 prc->numhcblks = 0;
2624 prc->numvcblks = 0;
2625 prc->cblks = 0;
2626 prc->incltagtree = 0;
2627 prc->numimsbstagtree = 0;
2628#endif
2629}
2630
2631static void jpc_band_init(jpc_dec_band_t *band)
2632{
2633#if 1
2634 memset(band, 0, sizeof(jpc_dec_band_t));
2635 band->prcs = 0;
2636 band->data = 0;
2637 band->orient = 0;
2638 band->stepsize = 0;
2639 band->absstepsize = 0;
2640 band->numbps = 0;
2641 band->analgain = 0;
2642 band->roishift = 0;
2643#endif
2644}
2645
2646static void jpc_rlvl_init(jpc_dec_rlvl_t *rlvl)
2647{
2648#if 1
2649 memset(rlvl, 0, sizeof(jpc_dec_rlvl_t));
2650 rlvl->numbands = 0;
2651 rlvl->bands = 0;
2652 rlvl->xstart = 0;
2653 rlvl->ystart = 0;
2654 rlvl->xend = 0;
2655 rlvl->yend = 0;
2656 rlvl->prcwidthexpn = 0;
2657 rlvl->prcheightexpn = 0;
2658 rlvl->numhprcs = 0;
2659 rlvl->numvprcs = 0;
2660 rlvl->numprcs = 0;
2661 rlvl->cbgwidthexpn = 0;
2662 rlvl->cblkheightexpn = 0;
2663#endif
2664}
2665
2666static void jpc_seglist_init(jpc_dec_seglist_t *seglist)
2667{
2668 memset(seglist, 0, sizeof(jpc_dec_seglist_t));
2669 seglist->head = 0;
2670 seglist->tail = 0;
2671}
jpc_dec.h+1−0
@@ -77,6 +77,7 @@ · 76 unmodified lines
77#include "jasper/jas_stream.h"77#include "jasper/jas_stream.h"
78#include "jasper/jas_image.h"78#include "jasper/jas_image.h"
79 79
80#include "jpc_cod.h"
80#include "jpc_tsfb.h"81#include "jpc_tsfb.h"
81#include "jpc_tagtree.h"82#include "jpc_tagtree.h"
82#include "jpc_cs.h"83#include "jpc_cs.h"
jpc_enc.c+2665−0
@@ -0,0 +1,2665 @@
1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2003 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64/*
65 * $Id$
66 */
67
68/******************************************************************************\
69* Includes.
70\******************************************************************************/
71
72#include "jpc_enc.h"
73#include "jpc_flt.h"
74#include "jpc_fix.h"
75#include "jpc_tagtree.h"
76#include "jpc_cs.h"
77#include "jpc_mct.h"
78#include "jpc_tsfb.h"
79#include "jpc_t1cod.h"
80#include "jpc_t1enc.h"
81#include "jpc_t2enc.h"
82#include "jpc_math.h"
83#include "jpc_util.h"
84
85#include "jasper/jas_types.h"
86#include "jasper/jas_string.h"
87#include "jasper/jas_malloc.h"
88#include "jasper/jas_image.h"
89#include "jasper/jas_tvp.h"
90#include "jasper/jas_version.h"
91#include "jasper/jas_math.h"
92#include "jasper/jas_debug.h"
93
94/******************************************************************************\
95*
96\******************************************************************************/
97
98#define JPC_POW2(n) \
99 (1 << (n))
100
101#define JPC_FLOORTOMULTPOW2(x, n) \
102 (((n) > 0) ? ((x) & (~((1 << n) - 1))) : (x))
103/* Round to the nearest multiple of the specified power of two in the
104 direction of negative infinity. */
105
106#define JPC_CEILTOMULTPOW2(x, n) \
107 (((n) > 0) ? JPC_FLOORTOMULTPOW2(((x) + (1 << (n)) - 1), n) : (x))
108/* Round to the nearest multiple of the specified power of two in the
109 direction of positive infinity. */
110
111#define JPC_POW2(n) \
112 (1 << (n))
113
114/******************************************************************************\
115* Local prototypes.
116\******************************************************************************/
117
118static jpc_enc_tile_t *jpc_enc_tile_create(jpc_enc_cp_t *cp, jas_image_t *image, int tileno);
119static void jpc_enc_tile_destroy(jpc_enc_tile_t *tile);
120
121static jpc_enc_tcmpt_t *tcmpt_create(jpc_enc_tcmpt_t *tcmpt, jpc_enc_cp_t *cp,
122 jas_image_t *image, jpc_enc_tile_t *tile);
123static void tcmpt_destroy(jpc_enc_tcmpt_t *tcmpt);
124static jpc_enc_rlvl_t *rlvl_create(jpc_enc_rlvl_t *rlvl, jpc_enc_cp_t *cp,
125 jpc_enc_tcmpt_t *tcmpt, jpc_tsfb_band_t *bandinfos);
126static void rlvl_destroy(jpc_enc_rlvl_t *rlvl);
127static jpc_enc_band_t *band_create(jpc_enc_band_t *band, jpc_enc_cp_t *cp,
128 jpc_enc_rlvl_t *rlvl, jpc_tsfb_band_t *bandinfos);
129static void band_destroy(jpc_enc_band_t *bands);
130static jpc_enc_prc_t *prc_create(jpc_enc_prc_t *prc,
131 jpc_enc_band_t *band);
132static void prc_destroy(jpc_enc_prc_t *prcs);
133static jpc_enc_cblk_t *cblk_create(jpc_enc_cblk_t *cblk,
134 jpc_enc_prc_t *prc);
135static void cblk_destroy(jpc_enc_cblk_t *cblks);
136int ratestrtosize(const char *s, uint_fast32_t rawsize, uint_fast32_t *size);
137static void pass_destroy(jpc_enc_pass_t *pass);
138void jpc_enc_dump(jpc_enc_t *enc);
139
140void calcrdslopes(jpc_enc_cblk_t *cblk);
141void dump_layeringinfo(jpc_enc_t *enc);
142void jpc_quantize(jas_matrix_t *data, jpc_fix_t stepsize);
143jpc_enc_t *jpc_enc_create(jpc_enc_cp_t *cp, jas_stream_t *out, jas_image_t *image);
144void jpc_enc_destroy(jpc_enc_t *enc);
145static int jpc_enc_encodemainhdr(jpc_enc_t *enc);
146static int jpc_enc_encodemainbody(jpc_enc_t *enc);
147int jpc_enc_encodetiledata(jpc_enc_t *enc);
148int rateallocate(jpc_enc_t *enc, unsigned numlyrs, uint_fast32_t *cumlens);
149static jpc_enc_cp_t *cp_create(const char *optstr, jas_image_t *image);
150void jpc_enc_cp_destroy(jpc_enc_cp_t *cp);
151static uint_fast32_t jpc_abstorelstepsize(jpc_fix_t absdelta, int scaleexpn);
152
153/******************************************************************************\
154* Types.
155\******************************************************************************/
156
157typedef enum {
158 OPT_DEBUG,
159 OPT_IMGAREAOFFX,
160 OPT_IMGAREAOFFY,
161 OPT_TILEGRDOFFX,
162 OPT_TILEGRDOFFY,
163 OPT_TILEWIDTH,
164 OPT_TILEHEIGHT,
165 OPT_PRCWIDTH,
166 OPT_PRCHEIGHT,
167 OPT_CBLKWIDTH,
168 OPT_CBLKHEIGHT,
169 OPT_MODE,
170 OPT_PRG,
171 OPT_NOMCT,
172 OPT_MAXRLVLS,
173 OPT_SOP,
174 OPT_EPH,
175 OPT_LAZY,
176 OPT_TERMALL,
177 OPT_SEGSYM,
178 OPT_VCAUSAL,
179 OPT_RESET,
180 OPT_PTERM,
181 OPT_NUMGBITS,
182 OPT_RATE,
183 OPT_ILYRRATES,
184 OPT_JP2OVERHEAD
185} optid_t;
186
187typedef enum {
188 PO_L = 0,
189 PO_R
190} poid_t;
191
192typedef enum {
193 MODE_INT,
194 MODE_REAL
195} modeid_t;
196
197/******************************************************************************\
198* Data.
199\******************************************************************************/
200
201static const jas_taginfo_t encopts[] = {
202 {OPT_DEBUG, "debug"},
203 {OPT_IMGAREAOFFX, "imgareatlx"},
204 {OPT_IMGAREAOFFY, "imgareatly"},
205 {OPT_TILEGRDOFFX, "tilegrdtlx"},
206 {OPT_TILEGRDOFFY, "tilegrdtly"},
207 {OPT_TILEWIDTH, "tilewidth"},
208 {OPT_TILEHEIGHT, "tileheight"},
209 {OPT_PRCWIDTH, "prcwidth"},
210 {OPT_PRCHEIGHT, "prcheight"},
211 {OPT_CBLKWIDTH, "cblkwidth"},
212 {OPT_CBLKHEIGHT, "cblkheight"},
213 {OPT_MODE, "mode"},
214 {OPT_PRG, "prg"},
215 {OPT_NOMCT, "nomct"},
216 {OPT_MAXRLVLS, "numrlvls"},
217 {OPT_SOP, "sop"},
218 {OPT_EPH, "eph"},
219 {OPT_LAZY, "lazy"},
220 {OPT_TERMALL, "termall"},
221 {OPT_SEGSYM, "segsym"},
222 {OPT_VCAUSAL, "vcausal"},
223 {OPT_PTERM, "pterm"},
224 {OPT_RESET, "resetprob"},
225 {OPT_NUMGBITS, "numgbits"},
226 {OPT_RATE, "rate"},
227 {OPT_ILYRRATES, "ilyrrates"},
228 {OPT_JP2OVERHEAD, "_jp2overhead"},
229 {-1, 0}
230};
231
232static const jas_taginfo_t prgordtab[] = {
233 {JPC_COD_LRCPPRG, "lrcp"},
234 {JPC_COD_RLCPPRG, "rlcp"},
235 {JPC_COD_RPCLPRG, "rpcl"},
236 {JPC_COD_PCRLPRG, "pcrl"},
237 {JPC_COD_CPRLPRG, "cprl"},
238 {-1, 0}
239};
240
241static const jas_taginfo_t modetab[] = {
242 {MODE_INT, "int"},
243 {MODE_REAL, "real"},
244 {-1, 0}
245};
246
247/******************************************************************************\
248\******************************************************************************/
249
250/**
251 * @return UINT_FAST32_MAX on error
252 */
253static uint_fast32_t jpc_abstorelstepsize(jpc_fix_t absdelta, int scaleexpn)
254{
255 int p;
256 uint_fast32_t mant;
257 uint_fast32_t expn;
258 int n;
259
260 if (absdelta < 0) {
261 return UINT_FAST32_MAX;
262 }
263
264 p = jpc_fix_firstone(absdelta) - JPC_FIX_FRACBITS;
265 n = 11 - jpc_fix_firstone(absdelta);
266 mant = ((n < 0) ? (absdelta >> (-n)) : (absdelta << n)) & 0x7ff;
267 expn = scaleexpn - p;
268 if (scaleexpn < p) {
269 return UINT_FAST32_MAX;
270 }
271 if (expn >= 0x1f)
272 return UINT_FAST32_MAX;
273 return JPC_QCX_EXPN(expn) | JPC_QCX_MANT(mant);
274}
275
276/******************************************************************************\
277* The main encoder entry point.
278\******************************************************************************/
279
280int jpc_encode(jas_image_t *image, jas_stream_t *out, const char *optstr)
281{
282 jpc_enc_t *enc;
283 jpc_enc_cp_t *cp;
284
285 enc = 0;
286
287 jpc_init();
288
289 if (!(cp = cp_create(optstr, image))) {
290 jas_logerrorf("invalid JP encoder options\n");
291 goto error;
292 }
293
294 if (!(enc = jpc_enc_create(cp, out, image))) {
295 jas_logerrorf("jpc_enc_create failed\n");
296 goto error;
297 }
298 cp = 0;
299
300 /* Encode the main header. */
301 if (jpc_enc_encodemainhdr(enc)) {
302 jas_logerrorf("cannot encode main header\n");
303 goto error;
304 }
305
306 /* Encode the main body. This constitutes most of the encoding work. */
307 if (jpc_enc_encodemainbody(enc)) {
308 jas_logerrorf("cannot encode main body\n");
309 goto error;
310 }
311
312 /* Write EOC marker segment. */
313 if (!(enc->mrk = jpc_ms_create(JPC_MS_EOC))) {
314 jas_logerrorf("cannot create EOC marker\n");
315 goto error;
316 }
317 if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
318 jas_logerrorf("cannot write EOC marker\n");
319 goto error;
320 }
321 jpc_ms_destroy(enc->mrk);
322 enc->mrk = 0;
323
324 if (jas_stream_flush(enc->out)) {
325 jas_logerrorf("stream flush failed\n");
326 goto error;
327 }
328
329 jpc_enc_destroy(enc);
330
331 return 0;
332
333error:
334 if (cp) {
335 jpc_enc_cp_destroy(cp);
336 }
337 if (enc) {
338 jpc_enc_destroy(enc);
339 }
340 jas_logerrorf("jpc_encode failed\n");
341 return -1;
342}
343
344/******************************************************************************\
345* Option parsing code.
346\******************************************************************************/
347
348static jpc_enc_cp_t *cp_create(const char *optstr, jas_image_t *image)
349{
350 jpc_enc_cp_t *cp;
351 jas_tvparser_t *tvp;
352 int numilyrrates;
353 double *ilyrrates;
354 int i;
355 int tagid;
356 jpc_enc_tcp_t *tcp;
357 jpc_enc_tccp_t *tccp;
358 jpc_enc_ccp_t *ccp;
359 uint_fast16_t rlvlno;
360 uint_fast16_t prcwidthexpn;
361 uint_fast16_t prcheightexpn;
362 bool enablemct;
363 uint_fast32_t jp2overhead;
364 uint_fast16_t lyrno;
365 uint_fast32_t hsteplcm;
366 uint_fast32_t vsteplcm;
367 bool mctvalid;
368
369 tvp = 0;
370 ilyrrates = 0;
371 numilyrrates = 0;
372
373 if (!(cp = jas_malloc(sizeof(jpc_enc_cp_t)))) {
374 goto error;
375 }
376
377 prcwidthexpn = 15;
378 prcheightexpn = 15;
379 enablemct = true;
380 jp2overhead = 0;
381
382 cp->ccps = 0;
383 cp->debug = 0;
384 cp->imgareatlx = UINT_FAST32_MAX;
385 cp->imgareatly = UINT_FAST32_MAX;
386 cp->refgrdwidth = 0;
387 cp->refgrdheight = 0;
388 cp->tilegrdoffx = UINT_FAST32_MAX;
389 cp->tilegrdoffy = UINT_FAST32_MAX;
390 cp->tilewidth = 0;
391 cp->tileheight = 0;
392 cp->numcmpts = jas_image_numcmpts(image);
393 cp->tcp.ilyrrates = NULL;
394
395 hsteplcm = 1;
396 vsteplcm = 1;
397 for (unsigned cmptno = 0; cmptno < jas_image_numcmpts(image); ++cmptno) {
398 if (jas_image_cmptbrx(image, cmptno) + jas_image_cmpthstep(image, cmptno) <=
399 jas_image_brx(image) || jas_image_cmptbry(image, cmptno) +
400 jas_image_cmptvstep(image, cmptno) <= jas_image_bry(image)) {
401 jas_logerrorf("unsupported image type\n");
402 goto error;
403 }
404 /* Note: We ought to be calculating the LCMs here. Fix some day. */
405 hsteplcm *= jas_image_cmpthstep(image, cmptno);
406 vsteplcm *= jas_image_cmptvstep(image, cmptno);
407 }
408
409 if (!(cp->ccps = jas_alloc2(cp->numcmpts, sizeof(jpc_enc_ccp_t)))) {
410 goto error;
411 }
412 unsigned cmptno;
413 for (cmptno = 0, ccp = cp->ccps; cmptno < cp->numcmpts; ++cmptno,
414 ++ccp) {
415 ccp->sampgrdstepx = jas_image_cmpthstep(image, cmptno);
416 ccp->sampgrdstepy = jas_image_cmptvstep(image, cmptno);
417 /* XXX - this isn't quite correct for more general image */
418 ccp->sampgrdsubstepx = 0;
419 ccp->sampgrdsubstepx = 0;
420 ccp->prec = jas_image_cmptprec(image, cmptno);
421 ccp->sgnd = jas_image_cmptsgnd(image, cmptno);
422 ccp->numstepsizes = 0;
423 memset(ccp->stepsizes, 0, sizeof(ccp->stepsizes));
424 }
425
426 cp->rawsize = jas_image_rawsize(image);
427 if (cp->rawsize == 0) {
428 /* prevent division by zero in cp_create() */
429 goto error;
430 }
431 cp->totalsize = UINT_FAST32_MAX;
432
433 tcp = &cp->tcp;
434 tcp->csty = 0;
435 tcp->intmode = true;
436 tcp->prg = JPC_COD_LRCPPRG;
437 tcp->numlyrs = 1;
438 tcp->ilyrrates = 0;
439
440 tccp = &cp->tccp;
441 tccp->csty = 0;
442 tccp->maxrlvls = 6;
443 tccp->cblkwidthexpn = 6;
444 tccp->cblkheightexpn = 6;
445 tccp->cblksty = 0;
446 tccp->numgbits = 2;
447
448 if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
449 goto error;
450 }
451
452 while (!jas_tvparser_next(tvp)) {
453 switch (jas_taginfo_nonull(jas_taginfos_lookup(encopts,
454 jas_tvparser_gettag(tvp)))->id) {
455 case OPT_DEBUG:
456 cp->debug = atoi(jas_tvparser_getval(tvp));
457 break;
458 case OPT_IMGAREAOFFX:
459 cp->imgareatlx = atoi(jas_tvparser_getval(tvp));
460 break;
461 case OPT_IMGAREAOFFY:
462 cp->imgareatly = atoi(jas_tvparser_getval(tvp));
463 break;
464 case OPT_TILEGRDOFFX:
465 cp->tilegrdoffx = atoi(jas_tvparser_getval(tvp));
466 break;
467 case OPT_TILEGRDOFFY:
468 cp->tilegrdoffy = atoi(jas_tvparser_getval(tvp));
469 break;
470 case OPT_TILEWIDTH:
471 cp->tilewidth = atoi(jas_tvparser_getval(tvp));
472 break;
473 case OPT_TILEHEIGHT:
474 cp->tileheight = atoi(jas_tvparser_getval(tvp));
475 break;
476 case OPT_PRCWIDTH:
477 prcwidthexpn = jpc_floorlog2(atoi(jas_tvparser_getval(tvp)));
478 break;
479 case OPT_PRCHEIGHT:
480 prcheightexpn = jpc_floorlog2(atoi(jas_tvparser_getval(tvp)));
481 break;
482 case OPT_CBLKWIDTH:
483 tccp->cblkwidthexpn =
484 jpc_floorlog2(atoi(jas_tvparser_getval(tvp)));
485 break;
486 case OPT_CBLKHEIGHT:
487 tccp->cblkheightexpn =
488 jpc_floorlog2(atoi(jas_tvparser_getval(tvp)));
489 break;
490 case OPT_MODE:
491 if ((tagid = jas_taginfo_nonull(jas_taginfos_lookup(modetab,
492 jas_tvparser_getval(tvp)))->id) < 0) {
493 jas_logwarnf("ignoring invalid mode %s\n",
494 jas_tvparser_getval(tvp));
495 } else {
496 tcp->intmode = (tagid == MODE_INT);
497 }
498 break;
499 case OPT_PRG:
500 if ((tagid = jas_taginfo_nonull(jas_taginfos_lookup(prgordtab,
501 jas_tvparser_getval(tvp)))->id) < 0) {
502 jas_logwarnf("ignoring invalid progression order %s\n",
503 jas_tvparser_getval(tvp));
504 } else {
505 tcp->prg = tagid;
506 }
507 break;
508 case OPT_NOMCT:
509 enablemct = false;
510 break;
511 case OPT_MAXRLVLS:
512 tccp->maxrlvls = atoi(jas_tvparser_getval(tvp));
513 if (tccp->maxrlvls > JPC_MAXRLVLS) {
514 jas_logerrorf("number of resolution levels exceeds maximum %d\n",
515 JPC_MAXRLVLS);
516 goto error;
517 }
518 break;
519 case OPT_SOP:
520 cp->tcp.csty |= JPC_COD_SOP;
521 break;
522 case OPT_EPH:
523 cp->tcp.csty |= JPC_COD_EPH;
524 break;
525 case OPT_LAZY:
526 tccp->cblksty |= JPC_COX_LAZY;
527 break;
528 case OPT_TERMALL:
529 tccp->cblksty |= JPC_COX_TERMALL;
530 break;
531 case OPT_SEGSYM:
532 tccp->cblksty |= JPC_COX_SEGSYM;
533 break;
534 case OPT_VCAUSAL:
535 tccp->cblksty |= JPC_COX_VSC;
536 break;
537 case OPT_RESET:
538 tccp->cblksty |= JPC_COX_RESET;
539 break;
540 case OPT_PTERM:
541 tccp->cblksty |= JPC_COX_PTERM;
542 break;
543 case OPT_NUMGBITS:
544 cp->tccp.numgbits = atoi(jas_tvparser_getval(tvp));
545 break;
546 case OPT_RATE:
547 if (ratestrtosize(jas_tvparser_getval(tvp), cp->rawsize,
548 &cp->totalsize)) {
549 jas_logwarnf("ignoring bad rate specifier %s\n",
550 jas_tvparser_getval(tvp));
551 }
552 break;
553 case OPT_ILYRRATES:
554 if (jpc_atoaf(jas_tvparser_getval(tvp), &numilyrrates,
555 &ilyrrates)) {
556 jas_logwarnf("warning: invalid intermediate layer rates specifier ignored (%s)\n",
557 jas_tvparser_getval(tvp));
558 }
559 break;
560
561 case OPT_JP2OVERHEAD:
562 jp2overhead = atoi(jas_tvparser_getval(tvp));
563 break;
564 default:
565 jas_logwarnf("warning: ignoring invalid option %s\n",
566 jas_tvparser_gettag(tvp));
567 break;
568 }
569 }
570
571 jas_tvparser_destroy(tvp);
572 tvp = 0;
573
574 if (cp->totalsize != UINT_FAST32_MAX) {
575 cp->totalsize = (cp->totalsize > jp2overhead) ?
576 (cp->totalsize - jp2overhead) : 0;
577 }
578
579 if (cp->imgareatlx == UINT_FAST32_MAX) {
580 cp->imgareatlx = 0;
581 } else {
582 if (hsteplcm != 1) {
583 jas_logwarnf("warning: overriding imgareatlx value\n");
584 }
585 cp->imgareatlx *= hsteplcm;
586 }
587 if (cp->imgareatly == UINT_FAST32_MAX) {
588 cp->imgareatly = 0;
589 } else {
590 if (vsteplcm != 1) {
591 jas_logwarnf("warning: overriding imgareatly value\n");
592 }
593 cp->imgareatly *= vsteplcm;
594 }
595 cp->refgrdwidth = cp->imgareatlx + jas_image_width(image);
596 cp->refgrdheight = cp->imgareatly + jas_image_height(image);
597 if (cp->tilegrdoffx == UINT_FAST32_MAX) {
598 cp->tilegrdoffx = cp->imgareatlx;
599 }
600 if (cp->tilegrdoffy == UINT_FAST32_MAX) {
601 cp->tilegrdoffy = cp->imgareatly;
602 }
603 if (!cp->tilewidth) {
604 cp->tilewidth = cp->refgrdwidth - cp->tilegrdoffx;
605 }
606 if (!cp->tileheight) {
607 cp->tileheight = cp->refgrdheight - cp->tilegrdoffy;
608 }
609
610 if (cp->numcmpts == 3) {
611 mctvalid = true;
612 for (cmptno = 0; cmptno < jas_image_numcmpts(image); ++cmptno) {
613 if (jas_image_cmptprec(image, cmptno) != jas_image_cmptprec(image, 0) ||
614 jas_image_cmptsgnd(image, cmptno) != jas_image_cmptsgnd(image, 0) ||
615 jas_image_cmptwidth(image, cmptno) != jas_image_cmptwidth(image, 0) ||
616 jas_image_cmptheight(image, cmptno) != jas_image_cmptheight(image, 0)) {
617 mctvalid = false;
618 }
619 }
620 } else {
621 mctvalid = false;
622 }
623 if (mctvalid && enablemct && jas_clrspc_fam(jas_image_clrspc(image)) != JAS_CLRSPC_FAM_RGB) {
624 jas_logwarnf("warning: color space apparently not RGB\n");
625 }
626 if (mctvalid && enablemct && jas_clrspc_fam(jas_image_clrspc(image)) == JAS_CLRSPC_FAM_RGB) {
627 tcp->mctid = (tcp->intmode) ? (JPC_MCT_RCT) : (JPC_MCT_ICT);
628 } else {
629 tcp->mctid = JPC_MCT_NONE;
630 }
631 tccp->qmfbid = (tcp->intmode) ? (JPC_COX_RFT) : (JPC_COX_INS);
632
633 for (rlvlno = 0; rlvlno < tccp->maxrlvls; ++rlvlno) {
634 tccp->prcwidthexpns[rlvlno] = prcwidthexpn;
635 tccp->prcheightexpns[rlvlno] = prcheightexpn;
636 }
637 if (prcwidthexpn != 15 || prcheightexpn != 15) {
638 tccp->csty |= JPC_COX_PRT;
639 }
640
641 /* Ensure that the tile width and height is valid. */
642 if (!cp->tilewidth) {
643 jas_logerrorf("invalid tile width %lu\n", (unsigned long)
644 cp->tilewidth);
645 goto error;
646 }
647 if (!cp->tileheight) {
648 jas_logerrorf("invalid tile height %lu\n", (unsigned long)
649 cp->tileheight);
650 goto error;
651 }
652
653 /* Ensure that the tile grid offset is valid. */
654 if (cp->tilegrdoffx > cp->imgareatlx ||
655 cp->tilegrdoffy > cp->imgareatly ||
656 cp->tilegrdoffx + cp->tilewidth < cp->imgareatlx ||
657 cp->tilegrdoffy + cp->tileheight < cp->imgareatly) {
658 jas_logerrorf("invalid tile grid offset (%lu, %lu)\n",
659 (unsigned long) cp->tilegrdoffx, (unsigned long)
660 cp->tilegrdoffy);
661 goto error;
662 }
663
664 cp->numhtiles = JPC_CEILDIV(cp->refgrdwidth - cp->tilegrdoffx,
665 cp->tilewidth);
666 cp->numvtiles = JPC_CEILDIV(cp->refgrdheight - cp->tilegrdoffy,
667 cp->tileheight);
668 cp->numtiles = cp->numhtiles * cp->numvtiles;
669
670 if (ilyrrates && numilyrrates > 0) {
671 tcp->numlyrs = numilyrrates + 1;
672 if (!(tcp->ilyrrates = jas_alloc2((tcp->numlyrs - 1),
673 sizeof(jpc_fix_t)))) {
674 goto error;
675 }
676 for (i = 0; i < JAS_CAST(int, tcp->numlyrs - 1); ++i) {
677 tcp->ilyrrates[i] = jpc_dbltofix(ilyrrates[i]);
678 }
679 }
680
681 /* Ensure that the integer mode is used in the case of lossless
682 coding. */
683 if (cp->totalsize == UINT_FAST32_MAX && (!cp->tcp.intmode)) {
684 jas_logerrorf("cannot use real mode for lossless coding\n");
685 goto error;
686 }
687
688 /* Ensure that the precinct width is valid. */
689 if (prcwidthexpn > 15) {
690 jas_logerrorf("invalid precinct width\n");
691 goto error;
692 }
693
694 /* Ensure that the precinct height is valid. */
695 if (prcheightexpn > 15) {
696 jas_logerrorf("invalid precinct height\n");
697 goto error;
698 }
699
700 /* Ensure that the code block width is valid. */
701 if (cp->tccp.cblkwidthexpn < 2 || cp->tccp.cblkwidthexpn > 12) {
702 jas_logerrorf("invalid code block width %d\n",
703 JPC_POW2(cp->tccp.cblkwidthexpn));
704 goto error;
705 }
706
707 /* Ensure that the code block height is valid. */
708 if (cp->tccp.cblkheightexpn < 2 || cp->tccp.cblkheightexpn > 12) {
709 jas_logerrorf("invalid code block height %d\n",
710 JPC_POW2(cp->tccp.cblkheightexpn));
711 goto error;
712 }
713
714 /* Ensure that the code block size is not too large. */
715 if (cp->tccp.cblkwidthexpn + cp->tccp.cblkheightexpn > 12) {
716 jas_logerrorf("code block size too large\n");
717 goto error;
718 }
719
720 /* Ensure that the number of layers is valid. */
721 if (cp->tcp.numlyrs > 16384) {
722 jas_logerrorf("too many layers\n");
723 goto error;
724 }
725
726 /* There must be at least one resolution level. */
727 if (cp->tccp.maxrlvls < 1) {
728 jas_logerrorf("must be at least one resolution level\n");
729 goto error;
730 }
731
732 /* Ensure that the number of guard bits is valid. */
733 if (cp->tccp.numgbits > 8) {
734 jas_logerrorf("invalid number of guard bits\n");
735 goto error;
736 }
737
738 /* Ensure that the rate is within the legal range. */
739 if (cp->totalsize != UINT_FAST32_MAX && cp->totalsize > cp->rawsize) {
740 jas_logwarnf("warning: specified rate is unreasonably large (%lu > %lu)\n", (unsigned long) cp->totalsize, (unsigned long) cp->rawsize);
741 }
742
743 /* Ensure that the intermediate layer rates are valid. */
744 if (tcp->numlyrs > 1) {
745 /* The intermediate layers rates must increase monotonically. */
746 for (lyrno = 0; lyrno + 2 < tcp->numlyrs; ++lyrno) {
747 if (tcp->ilyrrates[lyrno] >= tcp->ilyrrates[lyrno + 1]) {
748 jas_logerrorf("intermediate layer rates must increase monotonically\n");
749 goto error;
750 }
751 }
752 /* The intermediate layer rates must be less than the overall rate. */
753 if (cp->totalsize != UINT_FAST32_MAX) {
754 for (lyrno = 0; lyrno < tcp->numlyrs - 1; ++lyrno) {
755 if (jpc_fixtodbl(tcp->ilyrrates[lyrno]) > ((double) cp->totalsize)
756 / cp->rawsize) {
757 jas_logerrorf("warning: intermediate layer rates must be less than overall rate\n");
758 goto error;
759 }
760 }
761 }
762 }
763
764 if (ilyrrates) {
765 jas_free(ilyrrates);
766 }
767
768 return cp;
769
770error:
771
772 if (ilyrrates) {
773 jas_free(ilyrrates);
774 }
775 if (tvp) {
776 jas_tvparser_destroy(tvp);
777 }
778 if (cp) {
779 jpc_enc_cp_destroy(cp);
780 }
781 return 0;
782}
783
784void jpc_enc_cp_destroy(jpc_enc_cp_t *cp)
785{
786 if (cp->ccps) {
787 if (cp->tcp.ilyrrates) {
788 jas_free(cp->tcp.ilyrrates);
789 }
790 jas_free(cp->ccps);
791 }
792 jas_free(cp);
793}
794
795int ratestrtosize(const char *s, uint_fast32_t rawsize, uint_fast32_t *size)
796{
797 jpc_flt_t f;
798
799 /* Note: This function must not modify output size on failure. */
800 if (strchr(s, 'B')) {
801 *size = atoi(s);
802 } else {
803 f = atof(s);
804 if (f < 0) {
805 *size = 0;
806 } else if (f > 1.0) {
807 *size = rawsize + 1;
808 } else {
809 *size = f * rawsize;
810 }
811 }
812 return 0;
813}
814
815/******************************************************************************\
816* Encoder constructor and destructor.
817\******************************************************************************/
818
819jpc_enc_t *jpc_enc_create(jpc_enc_cp_t *cp, jas_stream_t *out, jas_image_t *image)
820{
821 jpc_enc_t *enc;
822
823 if (!(enc = jas_malloc(sizeof(jpc_enc_t)))) {
824 goto error;
825 }
826
827 enc->image = image;
828 enc->out = out;
829 enc->cp = cp;
830 enc->cstate = 0;
831 enc->tmpstream = 0;
832 enc->mrk = 0;
833 enc->curtile = 0;
834
835 if (!(enc->cstate = jpc_cstate_create())) {
836 goto error;
837 }
838 enc->len = 0;
839 enc->mainbodysize = 0;
840
841 return enc;
842
843error:
844
845 if (enc) {
846 jpc_enc_destroy(enc);
847 }
848 return 0;
849}
850
851void jpc_enc_destroy(jpc_enc_t *enc)
852{
853 /* The image object (i.e., enc->image) and output stream object
854 (i.e., enc->out) are created outside of the encoder.
855 Therefore, they must not be destroyed here. */
856
857 if (enc->curtile) {
858 jpc_enc_tile_destroy(enc->curtile);
859 }
860 if (enc->cp) {
861 jpc_enc_cp_destroy(enc->cp);
862 }
863 if (enc->cstate) {
864 jpc_cstate_destroy(enc->cstate);
865 }
866 if (enc->tmpstream) {
867 jas_stream_close(enc->tmpstream);
868 }
869 if (enc->mrk) {
870 jpc_ms_destroy(enc->mrk);
871 }
872
873 jas_free(enc);
874}
875
876/******************************************************************************\
877* Code.
878\******************************************************************************/
879
880static int jpc_enc_encodemainhdr(jpc_enc_t *enc)
881{
882 jpc_siz_t *siz;
883 jpc_cod_t *cod;
884 jpc_qcd_t *qcd;
885 int i;
886 long startoff;
887 long mainhdrlen;
888 jpc_enc_cp_t *cp;
889 jpc_qcc_t *qcc;
890 jpc_enc_tccp_t *tccp;
891 uint_fast16_t cmptno;
892 jpc_tsfb_band_t bandinfos[JPC_MAXBANDS];
893 jpc_enc_tcp_t *tcp;
894 jpc_tsfb_t *tsfb;
895 jpc_tsfb_band_t *bandinfo;
896 uint_fast16_t numbands;
897 uint_fast16_t bandno;
898 uint_fast16_t rlvlno;
899 uint_fast16_t analgain;
900 jpc_fix_t absstepsize;
901 char buf[1024];
902 jpc_com_t *com;
903
904 cp = enc->cp;
905
906 startoff = jas_stream_getrwcount(enc->out);
907
908 /* Write SOC marker segment. */
909 if (!(enc->mrk = jpc_ms_create(JPC_MS_SOC))) {
910 jas_logerrorf("cannot create SOC marker\n");
911 return -1;
912 }
913 if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
914 jas_logerrorf("cannot write SOC marker\n");
915 return -1;
916 }
917 jpc_ms_destroy(enc->mrk);
918 enc->mrk = 0;
919
920 /* Write SIZ marker segment. */
921 if (!(enc->mrk = jpc_ms_create(JPC_MS_SIZ))) {
922 jas_logerrorf("cannot create SIZ marker\n");
923 return -1;
924 }
925 siz = &enc->mrk->parms.siz;
926 siz->caps = 0;
927 siz->xoff = cp->imgareatlx;
928 siz->yoff = cp->imgareatly;
929 siz->width = cp->refgrdwidth;
930 siz->height = cp->refgrdheight;
931 siz->tilexoff = cp->tilegrdoffx;
932 siz->tileyoff = cp->tilegrdoffy;
933 siz->tilewidth = cp->tilewidth;
934 siz->tileheight = cp->tileheight;
935 siz->numcomps = cp->numcmpts;
936 siz->comps = jas_alloc2(siz->numcomps, sizeof(jpc_sizcomp_t));
937 assert(siz->comps);
938 for (i = 0; i < JAS_CAST(int, cp->numcmpts); ++i) {
939 siz->comps[i].prec = cp->ccps[i].prec;
940 siz->comps[i].sgnd = cp->ccps[i].sgnd;
941 siz->comps[i].hsamp = cp->ccps[i].sampgrdstepx;
942 siz->comps[i].vsamp = cp->ccps[i].sampgrdstepy;
943 }
944 if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
945 jas_logerrorf("cannot write SIZ marker\n");
946 return -1;
947 }
948 jpc_ms_destroy(enc->mrk);
949 enc->mrk = 0;
950
951 if (!(enc->mrk = jpc_ms_create(JPC_MS_COM))) {
952 jas_logerrorf("cannot create COM marker\n");
953 return -1;
954 }
955 sprintf(buf, "Creator: JasPer Version %s", jas_getversion());
956 com = &enc->mrk->parms.com;
957 com->len = JAS_CAST(uint_fast16_t, strlen(buf));
958 com->regid = JPC_COM_LATIN;
959 if (!(com->data = JAS_CAST(jas_uchar *, jas_strdup(buf)))) {
960 return -1;
961 }
962 if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
963 jas_logerrorf("cannot write COM marker\n");
964 return -1;
965 }
966 jpc_ms_destroy(enc->mrk);
967 enc->mrk = 0;
968
969#if 0
970 if (!(enc->mrk = jpc_ms_create(JPC_MS_CRG))) {
971 return -1;
972 }
973 crg = &enc->mrk->parms.crg;
974 crg->comps = jas_alloc2(crg->numcomps, sizeof(jpc_crgcomp_t));
975 if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
976 jas_logerrorf("cannot write CRG marker\n");
977 return -1;
978 }
979 jpc_ms_destroy(enc->mrk);
980 enc->mrk = 0;
981#endif
982
983 tcp = &cp->tcp;
984 tccp = &cp->tccp;
985 for (cmptno = 0; cmptno < cp->numcmpts; ++cmptno) {
986 tsfb = jpc_cod_gettsfb(tccp->qmfbid, tccp->maxrlvls - 1);
987 jpc_tsfb_getbands(tsfb, 0, 0, 1 << tccp->maxrlvls, 1 << tccp->maxrlvls,
988 bandinfos);
989 jpc_tsfb_destroy(tsfb);
990 numbands = 3 * tccp->maxrlvls - 2;
991 for (bandno = 0, bandinfo = bandinfos; bandno < numbands;
992 ++bandno, ++bandinfo) {
993 rlvlno = (bandno) ? ((bandno - 1) / 3 + 1) : 0;
994 analgain = JPC_NOMINALGAIN(tccp->qmfbid, tccp->maxrlvls,
995 rlvlno, bandinfo->orient);
996 if (!tcp->intmode) {
997 absstepsize = jpc_fix_div(jpc_inttofix(1 <<
998 (analgain + 1)), bandinfo->synenergywt);
999 } else {
1000 absstepsize = jpc_inttofix(1);
1001 }
1002 const uint_fast32_t stepsize =
1003 jpc_abstorelstepsize(absstepsize,
1004 cp->ccps[cmptno].prec + analgain);
1005 if (stepsize == UINT_FAST32_MAX)
1006 return -1;
1007 cp->ccps[cmptno].stepsizes[bandno] = stepsize;
1008 }
1009 cp->ccps[cmptno].numstepsizes = numbands;
1010 }
1011
1012 if (!(enc->mrk = jpc_ms_create(JPC_MS_COD))) {
1013 jas_logerrorf("cannot create COD marker\n");
1014 return -1;
1015 }
1016 cod = &enc->mrk->parms.cod;
1017 cod->csty = cp->tccp.csty | cp->tcp.csty;
1018 cod->compparms.csty = cp->tccp.csty | cp->tcp.csty;
1019 cod->compparms.numdlvls = cp->tccp.maxrlvls - 1;
1020 cod->compparms.numrlvls = cp->tccp.maxrlvls;
1021 cod->prg = cp->tcp.prg;
1022 cod->numlyrs = cp->tcp.numlyrs;
1023 cod->compparms.cblkwidthval = JPC_COX_CBLKSIZEEXPN(cp->tccp.cblkwidthexpn);
1024 cod->compparms.cblkheightval = JPC_COX_CBLKSIZEEXPN(cp->tccp.cblkheightexpn);
1025 cod->compparms.cblksty = cp->tccp.cblksty;
1026 cod->compparms.qmfbid = cp->tccp.qmfbid;
1027 cod->mctrans = (cp->tcp.mctid != JPC_MCT_NONE);
1028 if (tccp->csty & JPC_COX_PRT) {
1029 for (rlvlno = 0; rlvlno < tccp->maxrlvls; ++rlvlno) {
1030 cod->compparms.rlvls[rlvlno].parwidthval = tccp->prcwidthexpns[rlvlno];
1031 cod->compparms.rlvls[rlvlno].parheightval = tccp->prcheightexpns[rlvlno];
1032 }
1033 }
1034 if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
1035 jas_logerrorf("cannot write COD marker\n");
1036 return -1;
1037 }
1038 jpc_ms_destroy(enc->mrk);
1039 enc->mrk = 0;
1040
1041 if (!(enc->mrk = jpc_ms_create(JPC_MS_QCD))) {
1042 jas_logerrorf("cannot create QCD marker\n");
1043 return -1;
1044 }
1045 qcd = &enc->mrk->parms.qcd;
1046 qcd->compparms.qntsty = (tccp->qmfbid == JPC_COX_INS) ?
1047 JPC_QCX_SEQNT : JPC_QCX_NOQNT;
1048 qcd->compparms.numstepsizes = cp->ccps[0].numstepsizes;
1049 qcd->compparms.numguard = cp->tccp.numgbits;
1050 qcd->compparms.stepsizes = cp->ccps[0].stepsizes;
1051 if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
1052 jas_logerrorf("cannot write marker\n");
1053 return -1;
1054 }
1055 /* We do not want the step size array to be freed! */
1056 qcd->compparms.stepsizes = 0;
1057 jpc_ms_destroy(enc->mrk);
1058 enc->mrk = 0;
1059
1060 tccp = &cp->tccp;
1061 for (cmptno = 1; cmptno < cp->numcmpts; ++cmptno) {
1062 if (!(enc->mrk = jpc_ms_create(JPC_MS_QCC))) {
1063 jas_logerrorf("cannot create QCC marker\n");
1064 return -1;
1065 }
1066 qcc = &enc->mrk->parms.qcc;
1067 qcc->compno = cmptno;
1068 qcc->compparms.qntsty = (tccp->qmfbid == JPC_COX_INS) ?
1069 JPC_QCX_SEQNT : JPC_QCX_NOQNT;
1070 qcc->compparms.numstepsizes = cp->ccps[cmptno].numstepsizes;
1071 qcc->compparms.numguard = cp->tccp.numgbits;
1072 qcc->compparms.stepsizes = cp->ccps[cmptno].stepsizes;
1073 if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
1074 jas_logerrorf("cannot write marker\n");
1075 return -1;
1076 }
1077 /* We do not want the step size array to be freed! */
1078 qcc->compparms.stepsizes = 0;
1079 jpc_ms_destroy(enc->mrk);
1080 enc->mrk = 0;
1081 }
1082
1083#define MAINTLRLEN 2
1084 mainhdrlen = jas_stream_getrwcount(enc->out) - startoff;
1085 enc->len += mainhdrlen;
1086 if (enc->cp->totalsize != UINT_FAST32_MAX) {
1087 uint_fast32_t overhead;
1088 overhead = mainhdrlen + MAINTLRLEN;
1089 enc->mainbodysize = (enc->cp->totalsize >= overhead) ?
1090 (enc->cp->totalsize - overhead) : 0;
1091 } else {
1092 enc->mainbodysize = UINT_FAST32_MAX;
1093 }
1094
1095 return 0;
1096}
1097
1098static int jpc_enc_encodemainbody(jpc_enc_t *enc)
1099{
1100 int tileno;
1101 jpc_sot_t *sot;
1102 jpc_enc_tcmpt_t *comp;
1103 jpc_enc_tcmpt_t *endcomps;
1104 jpc_enc_band_t *band;
1105 jpc_enc_band_t *endbands;
1106 jpc_enc_rlvl_t *lvl;
1107 unsigned rlvlno;
1108 jpc_qcc_t *qcc;
1109 jpc_cod_t *cod;
1110 int adjust;
1111 int absbandno;
1112 long tilehdrlen;
1113 long tilelen;
1114 jpc_enc_tile_t *tile;
1115 jpc_enc_cp_t *cp;
1116 double rho;
1117 unsigned cmptno;
1118 int samestepsizes;
1119 jpc_enc_ccp_t *ccps;
1120 jpc_enc_tccp_t *tccp;
1121 int bandno;
1122 int mingbits;
1123 int actualnumbps;
1124 jpc_fix_t mxmag;
1125 jpc_fix_t mag;
1126 int numgbits;
1127
1128 cp = enc->cp;
1129
1130 for (tileno = 0; tileno < JAS_CAST(int, cp->numtiles); ++tileno) {
1131 if (!(enc->curtile = jpc_enc_tile_create(enc->cp, enc->image,
1132 tileno))) {
1133 jas_logerrorf("cannot create tile\n");
1134 return -1;
1135 }
1136
1137 tile = enc->curtile;
1138
1139 if (jas_get_debug_level() >= 10) {
1140 jpc_enc_dump(enc);
1141 }
1142
1143 for (cmptno = 0, comp = tile->tcmpts; cmptno < tile->numtcmpts; ++cmptno, ++comp) {
1144 if (!cp->ccps[cmptno].sgnd) {
1145 adjust = 1 << (cp->ccps[cmptno].prec - 1);
1146 for (jas_matind_t i = 0; i < jas_matrix_numrows(comp->data); ++i) {
1147 for (jas_matind_t j = 0; j < jas_matrix_numcols(comp->data); ++j) {
1148 *jas_matrix_getref(comp->data, i, j) -= adjust;
1149 }
1150 }
1151 }
1152 }
1153
1154 if (!tile->intmode) {
1155 endcomps = &tile->tcmpts[tile->numtcmpts];
1156 for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1157 jas_matrix_asl(comp->data, JPC_FIX_FRACBITS);
1158 }
1159 }
1160
1161 switch (tile->mctid) {
1162 case JPC_MCT_RCT:
1163assert(jas_image_numcmpts(enc->image) == 3);
1164 jpc_rct(tile->tcmpts[0].data, tile->tcmpts[1].data,
1165 tile->tcmpts[2].data);
1166 break;
1167 case JPC_MCT_ICT:
1168assert(jas_image_numcmpts(enc->image) == 3);
1169 jpc_ict(tile->tcmpts[0].data, tile->tcmpts[1].data,
1170 tile->tcmpts[2].data);
1171 break;
1172 default:
1173 break;
1174 }
1175
1176 for (unsigned i = 0; i < jas_image_numcmpts(enc->image); ++i) {
1177 comp = &tile->tcmpts[i];
1178 jpc_tsfb_analyze(comp->tsfb, comp->data);
1179
1180 }
1181
1182
1183 endcomps = &tile->tcmpts[tile->numtcmpts];
1184 for (cmptno = 0, comp = tile->tcmpts; comp != endcomps; ++cmptno, ++comp) {
1185 mingbits = 0;
1186 absbandno = 0;
1187 /* All bands must have a corresponding quantizer step size,
1188 even if they contain no samples and are never coded. */
1189 /* Some bands may not be hit by the loop below, so we must
1190 initialize all of the step sizes to a sane value. */
1191 memset(comp->stepsizes, 0, sizeof(comp->stepsizes));
1192 for (rlvlno = 0, lvl = comp->rlvls; rlvlno < comp->numrlvls; ++rlvlno, ++lvl) {
1193 if (!lvl->bands) {
1194 absbandno += rlvlno ? 3 : 1;
1195 continue;
1196 }
1197 endbands = &lvl->bands[lvl->numbands];
1198 for (band = lvl->bands; band != endbands; ++band) {
1199 if (!band->data) {
1200 ++absbandno;
1201 continue;
1202 }
1203 mxmag = 0;
1204 for (jas_matind_t y = 0; y < jas_matrix_numrows(band->data); ++y) {
1205 for (jas_matind_t x = 0; x < jas_matrix_numcols(band->data); ++x) {
1206 mag = JAS_ABS(jas_matrix_get(band->data, y, x));
1207 if (mag > mxmag) {
1208 mxmag = mag;
1209 }
1210 }
1211 }
1212 if (tile->intmode) {
1213 actualnumbps = jpc_fix_firstone(mxmag) + 1;
1214 } else {
1215 actualnumbps = jpc_fix_firstone(mxmag) + 1 - JPC_FIX_FRACBITS;
1216 }
1217 numgbits = actualnumbps - (cp->ccps[cmptno].prec - 1 +
1218 band->analgain);
1219#if 0
1220 jas_eprintf("%d %d mag=%d actual=%d numgbits=%d\n",
1221 cp->ccps[cmptno].prec, band->analgain, mxmag,
1222 actualnumbps, numgbits);
1223#endif
1224 if (numgbits > mingbits) {
1225 mingbits = numgbits;
1226 }
1227 if (!tile->intmode) {
1228 band->absstepsize = jpc_fix_div(jpc_inttofix(1
1229 << (band->analgain + 1)),
1230 band->synweight);
1231 } else {
1232 band->absstepsize = jpc_inttofix(1);
1233 }
1234 const uint_fast32_t stepsize = jpc_abstorelstepsize(
1235 band->absstepsize, cp->ccps[cmptno].prec +
1236 band->analgain);
1237 if (stepsize == UINT_FAST32_MAX)
1238 return -1;
1239 band->stepsize = stepsize;
1240 band->numbps = cp->tccp.numgbits +
1241 JPC_QCX_GETEXPN(band->stepsize) - 1;
1242
1243 if ((!tile->intmode) && band->data) {
1244 jpc_quantize(band->data, band->absstepsize);
1245 }
1246
1247 comp->stepsizes[absbandno] = band->stepsize;
1248 ++absbandno;
1249 }
1250 }
1251
1252 assert(JPC_FIX_FRACBITS >= JPC_NUMEXTRABITS);
1253 if (!tile->intmode) {
1254 jas_matrix_divpow2(comp->data, JPC_FIX_FRACBITS - JPC_NUMEXTRABITS);
1255 } else {
1256 jas_matrix_asl(comp->data, JPC_NUMEXTRABITS);
1257 }
1258
1259#if 0
1260 jas_eprintf("numgbits %d mingbits %d\n", cp->tccp.numgbits,
1261 mingbits);
1262#endif
1263 if (mingbits > cp->tccp.numgbits) {
1264 jas_logerrorf("error: too few guard bits (%d < %d)\n",
1265 cp->tccp.numgbits, mingbits);
1266 return -1;
1267 }
1268 }
1269
1270 if (!(enc->tmpstream = jas_stream_memopen(0, 0))) {
1271 jas_logerrorf("cannot open tmp file\n");
1272 return -1;
1273 }
1274
1275 /* Write the tile header. */
1276 if (!(enc->mrk = jpc_ms_create(JPC_MS_SOT))) {
1277 return -1;
1278 }
1279 sot = &enc->mrk->parms.sot;
1280 sot->len = 0;
1281 sot->tileno = tileno;
1282 sot->partno = 0;
1283 sot->numparts = 1;
1284 if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
1285 jas_logerrorf("cannot write SOT marker\n");
1286 return -1;
1287 }
1288 jpc_ms_destroy(enc->mrk);
1289 enc->mrk = 0;
1290
1291/************************************************************************/
1292/************************************************************************/
1293/************************************************************************/
1294
1295 tccp = &cp->tccp;
1296 for (cmptno = 0; cmptno < cp->numcmpts; ++cmptno) {
1297 comp = &tile->tcmpts[cmptno];
1298 if (comp->numrlvls != tccp->maxrlvls) {
1299 if (!(enc->mrk = jpc_ms_create(JPC_MS_COD))) {
1300 return -1;
1301 }
1302/* XXX = this is not really correct. we are using comp #0's precint sizes
1303and other characteristics */
1304 comp = &tile->tcmpts[0];
1305 cod = &enc->mrk->parms.cod;
1306 cod->compparms.csty = 0;
1307 cod->compparms.numdlvls = comp->numrlvls - 1;
1308 cod->prg = tile->prg;
1309 cod->numlyrs = tile->numlyrs;
1310 cod->compparms.cblkwidthval = JPC_COX_CBLKSIZEEXPN(comp->cblkwidthexpn);
1311 cod->compparms.cblkheightval = JPC_COX_CBLKSIZEEXPN(comp->cblkheightexpn);
1312 cod->compparms.cblksty = comp->cblksty;
1313 cod->compparms.qmfbid = comp->qmfbid;
1314 cod->mctrans = (tile->mctid != JPC_MCT_NONE);
1315 for (unsigned i = 0; i < comp->numrlvls; ++i) {
1316 cod->compparms.rlvls[i].parwidthval = comp->rlvls[i].prcwidthexpn;
1317 cod->compparms.rlvls[i].parheightval = comp->rlvls[i].prcheightexpn;
1318 }
1319 if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
1320 return -1;
1321 }
1322 jpc_ms_destroy(enc->mrk);
1323 enc->mrk = 0;
1324 }
1325 }
1326
1327 for (cmptno = 0, comp = tile->tcmpts; cmptno < cp->numcmpts; ++cmptno, ++comp) {
1328 ccps = &cp->ccps[cmptno];
1329 if (JAS_CAST(int, ccps->numstepsizes) == comp->numstepsizes) {
1330 samestepsizes = 1;
1331 for (bandno = 0; bandno < JAS_CAST(int, ccps->numstepsizes);
1332 ++bandno) {
1333 if (ccps->stepsizes[bandno] != comp->stepsizes[bandno]) {
1334 samestepsizes = 0;
1335 break;
1336 }
1337 }
1338 } else {
1339 samestepsizes = 0;
1340 }
1341 if (!samestepsizes) {
1342 if (!(enc->mrk = jpc_ms_create(JPC_MS_QCC))) {
1343 return -1;
1344 }
1345 qcc = &enc->mrk->parms.qcc;
1346 qcc->compno = cmptno;
1347 qcc->compparms.numguard = cp->tccp.numgbits;
1348 qcc->compparms.qntsty = (comp->qmfbid == JPC_COX_INS) ?
1349 JPC_QCX_SEQNT : JPC_QCX_NOQNT;
1350 qcc->compparms.numstepsizes = comp->numstepsizes;
1351 qcc->compparms.stepsizes = comp->stepsizes;
1352 if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
1353 return -1;
1354 }
1355 qcc->compparms.stepsizes = 0;
1356 jpc_ms_destroy(enc->mrk);
1357 enc->mrk = 0;
1358 }
1359 }
1360
1361 /* Write a SOD marker to indicate the end of the tile header. */
1362 if (!(enc->mrk = jpc_ms_create(JPC_MS_SOD))) {
1363 return -1;
1364 }
1365 if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
1366 jas_logerrorf("cannot write SOD marker\n");
1367 return -1;
1368 }
1369 jpc_ms_destroy(enc->mrk);
1370 enc->mrk = 0;
1371 tilehdrlen = jas_stream_getrwcount(enc->tmpstream);
1372 assert(tilehdrlen >= 0);
1373
1374/************************************************************************/
1375/************************************************************************/
1376/************************************************************************/
1377
1378 if (jpc_enc_enccblks(enc)) {
1379 return -1;
1380 }
1381
1382 cp = enc->cp;
1383 rho = (double) (tile->brx - tile->tlx) * (tile->bry - tile->tly) /
1384 ((cp->refgrdwidth - cp->imgareatlx) * (cp->refgrdheight -
1385 cp->imgareatly));
1386 tile->rawsize = cp->rawsize * rho;
1387
1388 for (unsigned lyrno = 0; lyrno < tile->numlyrs - 1; ++lyrno) {
1389 tile->lyrsizes[lyrno] = tile->rawsize * jpc_fixtodbl(
1390 cp->tcp.ilyrrates[lyrno]);
1391 }
1392
1393 if (cp->totalsize != UINT_FAST32_MAX) {
1394 tile->lyrsizes[tile->numlyrs - 1] = (rho * enc->mainbodysize);
1395 } else {
1396 tile->lyrsizes[tile->numlyrs - 1] = UINT_FAST32_MAX;
1397 }
1398
1399#if 0
1400 jas_eprintf("TESTING %ld %ld\n", cp->totalsize != UINT_FAST32_MAX,
1401 tile->lyrsizes[0]);
1402#endif
1403 for (unsigned lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {
1404 if (tile->lyrsizes[lyrno] != UINT_FAST32_MAX) {
1405 if (JAS_CAST(uint_fast32_t, tilehdrlen) <= tile->lyrsizes[lyrno]) {
1406 tile->lyrsizes[lyrno] -= tilehdrlen;
1407 } else {
1408 tile->lyrsizes[lyrno] = 0;
1409 }
1410 }
1411 }
1412
1413 if (rateallocate(enc, tile->numlyrs, tile->lyrsizes)) {
1414 return -1;
1415 }
1416
1417#if 0
1418 jas_eprintf("ENCODE TILE DATA\n");
1419#endif
1420 if (jpc_enc_encodetiledata(enc)) {
1421 jas_logerrorf("dotile failed\n");
1422 return -1;
1423 }
1424
1425/************************************************************************/
1426/************************************************************************/
1427/************************************************************************/
1428
1429/************************************************************************/
1430/************************************************************************/
1431/************************************************************************/
1432
1433 tilelen = jas_stream_tell(enc->tmpstream);
1434
1435 if (jas_stream_seek(enc->tmpstream, 6, SEEK_SET) < 0) {
1436 return -1;
1437 }
1438 jpc_putuint32(enc->tmpstream, tilelen);
1439
1440 if (jas_stream_seek(enc->tmpstream, 0, SEEK_SET) < 0) {
1441 return -1;
1442 }
1443 if (jpc_putdata(enc->out, enc->tmpstream, -1)) {
1444 return -1;
1445 }
1446 enc->len += tilelen;
1447
1448 jas_stream_close(enc->tmpstream);
1449 enc->tmpstream = 0;
1450
1451 jpc_enc_tile_destroy(enc->curtile);
1452 enc->curtile = 0;
1453
1454 }
1455
1456 return 0;
1457}
1458
1459int jpc_enc_encodetiledata(jpc_enc_t *enc)
1460{
1461assert(enc->tmpstream);
1462 if (jpc_enc_encpkts(enc, enc->tmpstream)) {
1463 return -1;
1464 }
1465 return 0;
1466}
1467
1468void jpc_quantize(jas_matrix_t *data, jpc_fix_t stepsize)
1469{
1470 jpc_fix_t t;
1471
1472 if (stepsize == jpc_inttofix(1)) {
1473 return;
1474 }
1475
1476 for (jas_matind_t i = 0; i < jas_matrix_numrows(data); ++i) {
1477 for (jas_matind_t j = 0; j < jas_matrix_numcols(data); ++j) {
1478 t = jas_matrix_get(data, i, j);
1479
1480{
1481 if (t < 0) {
1482 t = jpc_fix_neg(jpc_fix_div(jpc_fix_neg(t), stepsize));
1483 } else {
1484 t = jpc_fix_div(t, stepsize);
1485 }
1486}
1487
1488 jas_matrix_set(data, i, j, t);
1489 }
1490 }
1491}
1492
1493void calcrdslopes(jpc_enc_cblk_t *cblk)
1494{
1495 jpc_enc_pass_t *endpasses;
1496 jpc_enc_pass_t *pass0;
1497 jpc_enc_pass_t *pass1;
1498 jpc_enc_pass_t *pass2;
1499 jpc_flt_t slope0;
1500 jpc_flt_t slope;
1501 jpc_flt_t dd;
1502 long dr;
1503
1504 endpasses = &cblk->passes[cblk->numpasses];
1505 pass2 = cblk->passes;
1506 slope0 = 0;
1507 while (pass2 != endpasses) {
1508 pass0 = 0;
1509 for (pass1 = cblk->passes; pass1 != endpasses; ++pass1) {
1510 dd = pass1->cumwmsedec;
1511 dr = pass1->end;
1512 if (pass0) {
1513 dd -= pass0->cumwmsedec;
1514 dr -= pass0->end;
1515 }
1516 if (dd <= 0) {
1517 pass1->rdslope = JPC_BADRDSLOPE;
1518 if (pass1 >= pass2) {
1519 pass2 = &pass1[1];
1520 }
1521 continue;
1522 }
1523 if (pass1 < pass2 && pass1->rdslope <= 0) {
1524 continue;
1525 }
1526 if (!dr) {
1527 assert(pass0);
1528 pass0->rdslope = 0;
1529 break;
1530 }
1531 slope = dd / dr;
1532 if (pass0 && slope >= slope0) {
1533 pass0->rdslope = 0;
1534 break;
1535 }
1536 pass1->rdslope = slope;
1537 if (pass1 >= pass2) {
1538 pass2 = &pass1[1];
1539 }
1540 pass0 = pass1;
1541 slope0 = slope;
1542 }
1543 }
1544
1545#if 0
1546 for (pass0 = cblk->passes; pass0 != endpasses; ++pass0) {
1547if (pass0->rdslope > 0.0) {
1548 jas_eprintf("pass %02d nmsedec=%lf dec=%lf end=%d %lf\n", pass0 - cblk->passes,
1549 fixtodbl(pass0->nmsedec), pass0->wmsedec, pass0->end, pass0->rdslope);
1550}
1551 }
1552#endif
1553}
1554
1555void dump_layeringinfo(jpc_enc_t *enc)
1556{
1557
1558 jpc_enc_tcmpt_t *tcmpt;
1559 unsigned tcmptno;
1560 jpc_enc_rlvl_t *rlvl;
1561 unsigned rlvlno;
1562 jpc_enc_band_t *band;
1563 unsigned bandno;
1564 jpc_enc_prc_t *prc;
1565 unsigned prcno;
1566 jpc_enc_cblk_t *cblk;
1567 unsigned cblkno;
1568 jpc_enc_pass_t *pass;
1569 unsigned passno;
1570 jpc_enc_tile_t *tile;
1571
1572 tile = enc->curtile;
1573
1574 for (unsigned lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {
1575 jas_loginfof("lyrno = %02u\n", lyrno);
1576 for (tcmptno = 0, tcmpt = tile->tcmpts; tcmptno < tile->numtcmpts;
1577 ++tcmptno, ++tcmpt) {
1578 for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
1579 ++rlvlno, ++rlvl) {
1580 if (!rlvl->bands) {
1581 continue;
1582 }
1583 for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
1584 ++bandno, ++band) {
1585 if (!band->data) {
1586 continue;
1587 }
1588 for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs;
1589 ++prcno, ++prc) {
1590 if (!prc->cblks) {
1591 continue;
1592 }
1593 for (cblkno = 0, cblk = prc->cblks; cblkno <
1594 prc->numcblks; ++cblkno, ++cblk) {
1595 for (passno = 0, pass = cblk->passes; passno <
1596 cblk->numpasses && pass->lyrno == lyrno;
1597 ++passno, ++pass) {
1598 jas_loginfof("lyrno=%02d cmptno=%02d rlvlno=%02d bandno=%02d prcno=%02d cblkno=%03d passno=%03d\n",
1599 lyrno, tcmptno, rlvlno, bandno, prcno,
1600 cblkno, passno);
1601 }
1602 }
1603 }
1604 }
1605 }
1606 }
1607 }
1608}
1609
1610int rateallocate(jpc_enc_t *enc, unsigned numlyrs, uint_fast32_t *cumlens)
1611{
1612 int ret = 0;
1613 jpc_flt_t lo;
1614 jpc_flt_t hi;
1615 jas_stream_t *out;
1616 uint_fast32_t cumlen;
1617 jpc_flt_t thresh;
1618 jpc_flt_t goodthresh;
1619 int success;
1620 long pos;
1621 long oldpos;
1622 int numiters;
1623
1624 jpc_enc_tcmpt_t *comp;
1625 jpc_enc_tcmpt_t *endcomps;
1626 jpc_enc_rlvl_t *lvl;
1627 jpc_enc_rlvl_t *endlvls;
1628 jpc_enc_band_t *band;
1629 jpc_enc_band_t *endbands;
1630 jpc_enc_cblk_t *cblk;
1631 jpc_enc_cblk_t *endcblks;
1632 jpc_enc_pass_t *pass;
1633 jpc_enc_pass_t *endpasses;
1634 jpc_enc_pass_t *pass1;
1635 jpc_flt_t mxrdslope;
1636 jpc_flt_t mnrdslope;
1637 jpc_enc_tile_t *tile;
1638 jpc_enc_prc_t *prc;
1639 unsigned prcno;
1640
1641 JAS_LOGDEBUGF(10, "starting rate allocation\n");
1642
1643 tile = enc->curtile;
1644
1645 for (unsigned lyrno = 1; lyrno < numlyrs - 1; ++lyrno) {
1646 assert(cumlens[lyrno - 1] <= cumlens[lyrno]);
1647 }
1648
1649 if (!(out = jas_stream_memopen(0, 0))) {
1650 ret = -1;
1651 goto done;
1652 }
1653
1654 /* Find minimum and maximum R-D slope values. */
1655 mnrdslope = DBL_MAX;
1656 mxrdslope = 0;
1657 endcomps = &tile->tcmpts[tile->numtcmpts];
1658 for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1659 endlvls = &comp->rlvls[comp->numrlvls];
1660 for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
1661 if (!lvl->bands) {
1662 continue;
1663 }
1664 endbands = &lvl->bands[lvl->numbands];
1665 for (band = lvl->bands; band != endbands; ++band) {
1666 if (!band->data) {
1667 continue;
1668 }
1669 for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs;
1670 ++prcno, ++prc) {
1671 if (!prc->cblks) {
1672 continue;
1673 }
1674 endcblks = &prc->cblks[prc->numcblks];
1675 for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
1676 calcrdslopes(cblk);
1677 endpasses = &cblk->passes[cblk->numpasses];
1678 for (pass = cblk->passes; pass != endpasses; ++pass) {
1679 if (pass->rdslope > 0) {
1680 if (pass->rdslope < mnrdslope) {
1681 mnrdslope = pass->rdslope;
1682 }
1683 if (pass->rdslope > mxrdslope) {
1684 mxrdslope = pass->rdslope;
1685 }
1686 }
1687 }
1688 }
1689 }
1690 }
1691 }
1692 }
1693 JAS_LOGDEBUGF(10, "min rdslope = %f max rdslope = %f\n", mnrdslope,
1694 mxrdslope);
1695
1696 jpc_init_t2state(enc, true);
1697
1698 for (unsigned lyrno = 0; lyrno < numlyrs; ++lyrno) {
1699
1700 lo = mnrdslope;
1701 hi = mxrdslope;
1702
1703 success = 0;
1704 goodthresh = 0;
1705 numiters = 0;
1706
1707 do {
1708
1709 cumlen = cumlens[lyrno];
1710 if (cumlen == UINT_FAST32_MAX) {
1711 /* Only the last layer can be free of a rate
1712 constraint (e.g., for lossless coding). */
1713 assert(lyrno == numlyrs - 1);
1714 goodthresh = -1;
1715 success = 1;
1716 break;
1717 }
1718
1719 thresh = (lo + hi) / 2;
1720
1721 /* Save the tier 2 coding state. */
1722 jpc_save_t2state(enc);
1723 oldpos = jas_stream_tell(out);
1724 assert(oldpos >= 0);
1725
1726 /* Assign all passes with R-D slopes greater than or
1727 equal to the current threshold to this layer. */
1728 endcomps = &tile->tcmpts[tile->numtcmpts];
1729 for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1730 endlvls = &comp->rlvls[comp->numrlvls];
1731 for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
1732 if (!lvl->bands) {
1733 continue;
1734 }
1735 endbands = &lvl->bands[lvl->numbands];
1736 for (band = lvl->bands; band != endbands; ++band) {
1737 if (!band->data) {
1738 continue;
1739 }
1740 for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs;
1741 ++prcno, ++prc) {
1742 if (!prc->cblks) {
1743 continue;
1744 }
1745 endcblks = &prc->cblks[prc->numcblks];
1746 for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
1747 if (cblk->curpass) {
1748 endpasses = &cblk->passes[cblk->numpasses];
1749 pass1 = cblk->curpass;
1750 for (pass = cblk->curpass; pass !=
1751 endpasses; ++pass) {
1752 if (pass->rdslope >= thresh) {
1753 pass1 = &pass[1];
1754 }
1755 }
1756 for (pass = cblk->curpass; pass != pass1;
1757 ++pass) {
1758 pass->lyrno = lyrno;
1759 }
1760 for (; pass != endpasses; ++pass) {
1761 pass->lyrno = -1;
1762 }
1763 }
1764 }
1765 }
1766 }
1767 }
1768 }
1769
1770 /* Perform tier 2 coding. */
1771 endcomps = &tile->tcmpts[tile->numtcmpts];
1772 for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1773 endlvls = &comp->rlvls[comp->numrlvls];
1774 for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
1775 if (!lvl->bands) {
1776 continue;
1777 }
1778 for (prcno = 0; prcno < lvl->numprcs; ++prcno) {
1779 if (jpc_enc_encpkt(enc, out, comp - tile->tcmpts,
1780 lvl - comp->rlvls, prcno, lyrno)) {
1781 ret = -1;
1782 goto done;
1783 }
1784 }
1785 }
1786 }
1787
1788 pos = jas_stream_tell(out);
1789
1790 /* Check the rate constraint. */
1791 assert(pos >= 0);
1792 if ((uint_fast32_t)pos > cumlen) {
1793 /* The rate is too high. */
1794 lo = thresh;
1795 } else if ((uint_fast32_t)pos <= cumlen) {
1796 /* The rate is low enough, so try higher. */
1797 hi = thresh;
1798 if (!success || thresh < goodthresh) {
1799 goodthresh = thresh;
1800 success = 1;
1801 }
1802 }
1803
1804 /* Save the tier 2 coding state. */
1805 jpc_restore_t2state(enc);
1806 if (jas_stream_seek(out, oldpos, SEEK_SET) < 0) {
1807 ret = -1;
1808 goto done;
1809 }
1810
1811 JAS_LOGDEBUGF(10, "maxlen=%08ld actuallen=%08ld thresh=%f\n",
1812 cumlen, pos, thresh);
1813
1814 ++numiters;
1815 } while (lo < hi - 1e-3 && numiters < 32);
1816
1817 if (!success) {
1818 jas_logwarnf("warning: empty layer generated\n");
1819 }
1820
1821 JAS_LOGDEBUGF(10, "success %d goodthresh %f\n", success, goodthresh);
1822
1823 /* Assign all passes with R-D slopes greater than or
1824 equal to the selected threshold to this layer. */
1825 endcomps = &tile->tcmpts[tile->numtcmpts];
1826 for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1827 endlvls = &comp->rlvls[comp->numrlvls];
1828 for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
1829 if (!lvl->bands) {
1830 continue;
1831 }
1832 endbands = &lvl->bands[lvl->numbands];
1833 for (band = lvl->bands; band != endbands; ++band) {
1834 if (!band->data) {
1835 continue;
1836 }
1837 for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs;
1838 ++prcno, ++prc) {
1839 if (!prc->cblks) {
1840 continue;
1841 }
1842 endcblks = &prc->cblks[prc->numcblks];
1843 for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
1844 if (cblk->curpass) {
1845 endpasses = &cblk->passes[cblk->numpasses];
1846 pass1 = cblk->curpass;
1847 if (success) {
1848 for (pass = cblk->curpass; pass !=
1849 endpasses; ++pass) {
1850 if (pass->rdslope >= goodthresh) {
1851 pass1 = &pass[1];
1852 }
1853 }
1854 }
1855 for (pass = cblk->curpass; pass != pass1;
1856 ++pass) {
1857 pass->lyrno = lyrno;
1858 }
1859 for (; pass != endpasses; ++pass) {
1860 pass->lyrno = -1;
1861 }
1862 }
1863 }
1864 }
1865 }
1866 }
1867 }
1868
1869 /* Perform tier 2 coding. */
1870 endcomps = &tile->tcmpts[tile->numtcmpts];
1871 for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1872 endlvls = &comp->rlvls[comp->numrlvls];
1873 for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
1874 if (!lvl->bands) {
1875 continue;
1876 }
1877 for (prcno = 0; prcno < lvl->numprcs; ++prcno) {
1878 if (jpc_enc_encpkt(enc, out, comp - tile->tcmpts,
1879 lvl - comp->rlvls, prcno, lyrno)) {
1880 ret = -1;
1881 goto done;
1882 }
1883 }
1884 }
1885 }
1886 }
1887
1888 if (jas_get_debug_level() >= 5) {
1889 dump_layeringinfo(enc);
1890 }
1891
1892 jas_stream_close(out);
1893 out = 0;
1894
1895done:
1896
1897 if (out) {
1898 jas_stream_close(out);
1899 }
1900
1901 JAS_LOGDEBUGF(10, "finished rate allocation\n");
1902
1903 return ret;
1904}
1905
1906/******************************************************************************\
1907* Tile constructors and destructors.
1908\******************************************************************************/
1909
1910static jpc_enc_tile_t *jpc_enc_tile_create(jpc_enc_cp_t *cp, jas_image_t *image, int tileno)
1911{
1912 jpc_enc_tile_t *tile;
1913 uint_fast32_t htileno;
1914 uint_fast32_t vtileno;
1915 uint_fast16_t lyrno;
1916 uint_fast16_t cmptno;
1917 jpc_enc_tcmpt_t *tcmpt;
1918
1919 if (!(tile = jas_malloc(sizeof(jpc_enc_tile_t)))) {
1920 goto error;
1921 }
1922
1923 /* Initialize a few members used in error recovery. */
1924 tile->tcmpts = 0;
1925 tile->lyrsizes = 0;
1926 tile->numtcmpts = cp->numcmpts;
1927 tile->pi = 0;
1928
1929 tile->tileno = tileno;
1930 htileno = tileno % cp->numhtiles;
1931 vtileno = tileno / cp->numhtiles;
1932
1933 /* Calculate the coordinates of the top-left and bottom-right
1934 corners of the tile. */
1935 tile->tlx = JAS_MAX(cp->tilegrdoffx + htileno * cp->tilewidth,
1936 cp->imgareatlx);
1937 tile->tly = JAS_MAX(cp->tilegrdoffy + vtileno * cp->tileheight,
1938 cp->imgareatly);
1939 tile->brx = JAS_MIN(cp->tilegrdoffx + (htileno + 1) * cp->tilewidth,
1940 cp->refgrdwidth);
1941 tile->bry = JAS_MIN(cp->tilegrdoffy + (vtileno + 1) * cp->tileheight,
1942 cp->refgrdheight);
1943
1944 /* Initialize some tile coding parameters. */
1945 tile->intmode = cp->tcp.intmode;
1946 tile->csty = cp->tcp.csty;
1947 tile->prg = cp->tcp.prg;
1948 tile->mctid = cp->tcp.mctid;
1949
1950 tile->numlyrs = cp->tcp.numlyrs;
1951 if (!(tile->lyrsizes = jas_alloc2(tile->numlyrs,
1952 sizeof(uint_fast32_t)))) {
1953 goto error;
1954 }
1955 for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {
1956 tile->lyrsizes[lyrno] = 0;
1957 }
1958
1959 /* Allocate an array for the per-tile-component information. */
1960 if (!(tile->tcmpts = jas_alloc2(cp->numcmpts, sizeof(jpc_enc_tcmpt_t)))) {
1961 goto error;
1962 }
1963 /* Initialize a few members critical for error recovery. */
1964 for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
1965 ++cmptno, ++tcmpt) {
1966 tcmpt->rlvls = 0;
1967 tcmpt->tsfb = 0;
1968 tcmpt->data = 0;
1969 }
1970 /* Initialize the per-tile-component information. */
1971 for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
1972 ++cmptno, ++tcmpt) {
1973 if (!tcmpt_create(tcmpt, cp, image, tile)) {
1974 goto error;
1975 }
1976 }
1977
1978 /* Initialize the synthesis weights for the MCT. */
1979 switch (tile->mctid) {
1980 case JPC_MCT_RCT:
1981 tile->tcmpts[0].synweight = jpc_dbltofix(sqrt(3.0));
1982 tile->tcmpts[1].synweight = jpc_dbltofix(sqrt(0.6875));
1983 tile->tcmpts[2].synweight = jpc_dbltofix(sqrt(0.6875));
1984 break;
1985 case JPC_MCT_ICT:
1986 tile->tcmpts[0].synweight = jpc_dbltofix(sqrt(3.0000));
1987 tile->tcmpts[1].synweight = jpc_dbltofix(sqrt(3.2584));
1988 tile->tcmpts[2].synweight = jpc_dbltofix(sqrt(2.4755));
1989 break;
1990 default:
1991 case JPC_MCT_NONE:
1992 for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
1993 ++cmptno, ++tcmpt) {
1994 tcmpt->synweight = JPC_FIX_ONE;
1995 }
1996 break;
1997 }
1998
1999 if (!(tile->pi = jpc_enc_pi_create(cp, tile))) {
2000 goto error;
2001 }
2002
2003 return tile;
2004
2005error:
2006
2007 if (tile) {
2008 jpc_enc_tile_destroy(tile);
2009 }
2010 return 0;
2011}
2012
2013/* Note: I don't think that it is necessary to marked destroyed subobjects
2014as such in this function. */
2015static void jpc_enc_tile_destroy(jpc_enc_tile_t *tile)
2016{
2017 jpc_enc_tcmpt_t *tcmpt;
2018 uint_fast16_t cmptno;
2019
2020 if (tile->tcmpts) {
2021 for (cmptno = 0, tcmpt = tile->tcmpts; cmptno <
2022 tile->numtcmpts; ++cmptno, ++tcmpt) {
2023 tcmpt_destroy(tcmpt);
2024 }
2025 jas_free(tile->tcmpts);
2026 /* tile->tcmpts = NULL; */
2027 }
2028 if (tile->lyrsizes) {
2029 jas_free(tile->lyrsizes);
2030 /* tile->lyrsizes = NULL; */
2031 }
2032 if (tile->pi) {
2033 jpc_pi_destroy(tile->pi);
2034 /* tile->pi = NULL; */
2035 }
2036 jas_free(tile);
2037 /* tile = NULL; */
2038}
2039
2040/* Note: This constructor creates the object in place. */
2041static jpc_enc_tcmpt_t *tcmpt_create(jpc_enc_tcmpt_t *tcmpt, jpc_enc_cp_t *cp,
2042 jas_image_t *image, jpc_enc_tile_t *tile)
2043{
2044 uint_fast16_t cmptno;
2045 uint_fast16_t rlvlno;
2046 jpc_enc_rlvl_t *rlvl;
2047 uint_fast32_t tlx;
2048 uint_fast32_t tly;
2049 uint_fast32_t brx;
2050 uint_fast32_t bry;
2051 uint_fast32_t cmpttlx;
2052 uint_fast32_t cmpttly;
2053 jpc_enc_ccp_t *ccp;
2054 jpc_tsfb_band_t bandinfos[JPC_MAXBANDS];
2055
2056 tcmpt->tile = tile;
2057 tcmpt->tsfb = 0;
2058 tcmpt->data = 0;
2059 tcmpt->rlvls = 0;
2060
2061 /* Deduce the component number. */
2062 cmptno = tcmpt - tile->tcmpts;
2063
2064 ccp = &cp->ccps[cmptno];
2065
2066 /* Compute the coordinates of the top-left and bottom-right
2067 corners of this tile-component. */
2068 tlx = JPC_CEILDIV(tile->tlx, ccp->sampgrdstepx);
2069 tly = JPC_CEILDIV(tile->tly, ccp->sampgrdstepy);
2070 brx = JPC_CEILDIV(tile->brx, ccp->sampgrdstepx);
2071 bry = JPC_CEILDIV(tile->bry, ccp->sampgrdstepy);
2072
2073 /* Create a sequence to hold the tile-component sample data. */
2074 if (!(tcmpt->data = jas_seq2d_create(tlx, tly, brx, bry))) {
2075 goto error;
2076 }
2077
2078 /* Get the image data associated with this tile-component. */
2079 cmpttlx = JPC_CEILDIV(cp->imgareatlx, ccp->sampgrdstepx);
2080 cmpttly = JPC_CEILDIV(cp->imgareatly, ccp->sampgrdstepy);
2081 if (jas_image_readcmpt(image, cmptno, tlx - cmpttlx, tly - cmpttly,
2082 brx - tlx, bry - tly, tcmpt->data)) {
2083 goto error;
2084 }
2085
2086 tcmpt->synweight = 0;
2087 tcmpt->qmfbid = cp->tccp.qmfbid;
2088 tcmpt->numrlvls = cp->tccp.maxrlvls;
2089 tcmpt->numbands = 3 * tcmpt->numrlvls - 2;
2090 if (!(tcmpt->tsfb = jpc_cod_gettsfb(tcmpt->qmfbid, tcmpt->numrlvls - 1))) {
2091 goto error;
2092 }
2093
2094 for (rlvlno = 0; rlvlno < tcmpt->numrlvls; ++rlvlno) {
2095 tcmpt->prcwidthexpns[rlvlno] = cp->tccp.prcwidthexpns[rlvlno];
2096 tcmpt->prcheightexpns[rlvlno] = cp->tccp.prcheightexpns[rlvlno];
2097 }
2098 tcmpt->cblkwidthexpn = cp->tccp.cblkwidthexpn;
2099 tcmpt->cblkheightexpn = cp->tccp.cblkheightexpn;
2100 tcmpt->cblksty = cp->tccp.cblksty;
2101 tcmpt->csty = cp->tccp.csty;
2102
2103 tcmpt->numstepsizes = tcmpt->numbands;
2104 assert(tcmpt->numstepsizes <= JPC_MAXBANDS);
2105 memset(tcmpt->stepsizes, 0, tcmpt->numstepsizes * sizeof(uint_fast16_t));
2106
2107 /* Retrieve information about the various bands. */
2108 jpc_tsfb_getbands(tcmpt->tsfb, jas_seq2d_xstart(tcmpt->data),
2109 jas_seq2d_ystart(tcmpt->data), jas_seq2d_xend(tcmpt->data),
2110 jas_seq2d_yend(tcmpt->data), bandinfos);
2111
2112 if (!(tcmpt->rlvls = jas_alloc2(tcmpt->numrlvls, sizeof(jpc_enc_rlvl_t)))) {
2113 goto error;
2114 }
2115 for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
2116 ++rlvlno, ++rlvl) {
2117 rlvl->bands = 0;
2118 rlvl->tcmpt = tcmpt;
2119 }
2120 for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
2121 ++rlvlno, ++rlvl) {
2122 if (!rlvl_create(rlvl, cp, tcmpt, bandinfos)) {
2123 goto error;
2124 }
2125 }
2126
2127 return tcmpt;
2128
2129error:
2130
2131 tcmpt_destroy(tcmpt);
2132 return 0;
2133
2134}
2135
2136/* Note: Since jpc_enc_tcmpt_t objects are created in-place, they might
2137potentially be destroyed multiple times at different levels in the call
2138chain. So, destroyed subobjects must be marked as destroyed to prevent
2139problems such as double frees. */
2140static void tcmpt_destroy(jpc_enc_tcmpt_t *tcmpt)
2141{
2142 jpc_enc_rlvl_t *rlvl;
2143 uint_fast16_t rlvlno;
2144
2145 if (tcmpt->rlvls) {
2146 for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
2147 ++rlvlno, ++rlvl) {
2148 rlvl_destroy(rlvl);
2149 }
2150 jas_free(tcmpt->rlvls);
2151 tcmpt->rlvls = NULL;
2152 }
2153
2154 if (tcmpt->data) {
2155 jas_seq2d_destroy(tcmpt->data);
2156 tcmpt->data = NULL;
2157 }
2158 if (tcmpt->tsfb) {
2159 jpc_tsfb_destroy(tcmpt->tsfb);
2160 tcmpt->tsfb = NULL;
2161 }
2162}
2163
2164/* Note: This constructor creates the object in place. */
2165static jpc_enc_rlvl_t *rlvl_create(jpc_enc_rlvl_t *rlvl, jpc_enc_cp_t *cp,
2166 jpc_enc_tcmpt_t *tcmpt, jpc_tsfb_band_t *bandinfos)
2167{
2168 uint_fast16_t rlvlno;
2169 uint_fast32_t tlprctlx;
2170 uint_fast32_t tlprctly;
2171 uint_fast32_t brprcbrx;
2172 uint_fast32_t brprcbry;
2173 uint_fast16_t bandno;
2174 jpc_enc_band_t *band;
2175
2176 /* Deduce the resolution level. */
2177 rlvlno = rlvl - tcmpt->rlvls;
2178
2179 /* Initialize members required for error recovery. */
2180 rlvl->bands = 0;
2181 rlvl->tcmpt = tcmpt;
2182
2183 /* Compute the coordinates of the top-left and bottom-right
2184 corners of the tile-component at this resolution. */
2185 rlvl->tlx = JPC_CEILDIVPOW2(JAS_CAST(uint_fast32_t,
2186 jas_seq2d_xstart(tcmpt->data)), tcmpt->numrlvls - 1 - rlvlno);
2187 rlvl->tly = JPC_CEILDIVPOW2(JAS_CAST(uint_fast32_t,
2188 jas_seq2d_ystart(tcmpt->data)), tcmpt->numrlvls - 1 - rlvlno);
2189 rlvl->brx = JPC_CEILDIVPOW2(JAS_CAST(uint_fast32_t,
2190 jas_seq2d_xend(tcmpt->data)), tcmpt->numrlvls - 1 - rlvlno);
2191 rlvl->bry = JPC_CEILDIVPOW2(JAS_CAST(uint_fast32_t,
2192 jas_seq2d_yend(tcmpt->data)), tcmpt->numrlvls - 1 - rlvlno);
2193
2194 if (rlvl->tlx >= rlvl->brx || rlvl->tly >= rlvl->bry) {
2195 rlvl->numhprcs = 0;
2196 rlvl->numvprcs = 0;
2197 rlvl->numprcs = 0;
2198 return rlvl;
2199 }
2200
2201 rlvl->numbands = (!rlvlno) ? 1 : 3;
2202 rlvl->prcwidthexpn = cp->tccp.prcwidthexpns[rlvlno];
2203 rlvl->prcheightexpn = cp->tccp.prcheightexpns[rlvlno];
2204 if (!rlvlno) {
2205 rlvl->cbgwidthexpn = rlvl->prcwidthexpn;
2206 rlvl->cbgheightexpn = rlvl->prcheightexpn;
2207 } else {
2208 rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1;
2209 rlvl->cbgheightexpn = rlvl->prcheightexpn - 1;
2210 }
2211 rlvl->cblkwidthexpn = JAS_MIN(cp->tccp.cblkwidthexpn, rlvl->cbgwidthexpn);
2212 rlvl->cblkheightexpn = JAS_MIN(cp->tccp.cblkheightexpn, rlvl->cbgheightexpn);
2213
2214 /* Compute the number of precincts. */
2215 tlprctlx = JPC_FLOORTOMULTPOW2(rlvl->tlx, rlvl->prcwidthexpn);
2216 tlprctly = JPC_FLOORTOMULTPOW2(rlvl->tly, rlvl->prcheightexpn);
2217 brprcbrx = JPC_CEILTOMULTPOW2(rlvl->brx, rlvl->prcwidthexpn);
2218 brprcbry = JPC_CEILTOMULTPOW2(rlvl->bry, rlvl->prcheightexpn);
2219 rlvl->numhprcs = JPC_FLOORDIVPOW2(brprcbrx - tlprctlx, rlvl->prcwidthexpn);
2220 rlvl->numvprcs = JPC_FLOORDIVPOW2(brprcbry - tlprctly, rlvl->prcheightexpn);
2221 rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs;
2222
2223 if (!(rlvl->bands = jas_alloc2(rlvl->numbands, sizeof(jpc_enc_band_t)))) {
2224 goto error;
2225 }
2226 for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
2227 ++bandno, ++band) {
2228 band->prcs = 0;
2229 band->data = 0;
2230 band->rlvl = rlvl;
2231 }
2232 for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
2233 ++bandno, ++band) {
2234 if (!band_create(band, cp, rlvl, bandinfos)) {
2235 goto error;
2236 }
2237 }
2238
2239 return rlvl;
2240error:
2241
2242 rlvl_destroy(rlvl);
2243 return 0;
2244}
2245
2246/* Note: Since jpc_enc_rlvl_t objects are created in-place, they might
2247potentially be destroyed multiple times at different levels in the call
2248chain. So, destroyed subobjects must be marked as destroyed to prevent
2249problems such as double frees. */
2250static void rlvl_destroy(jpc_enc_rlvl_t *rlvl)
2251{
2252 jpc_enc_band_t *band;
2253 uint_fast16_t bandno;
2254
2255 if (rlvl->bands) {
2256 for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
2257 ++bandno, ++band) {
2258 band_destroy(band);
2259 }
2260 jas_free(rlvl->bands);
2261 rlvl->bands = NULL;
2262 }
2263}
2264
2265/* Note: This constructor creates the object in place. */
2266static jpc_enc_band_t *band_create(jpc_enc_band_t *band, jpc_enc_cp_t *cp,
2267 jpc_enc_rlvl_t *rlvl, jpc_tsfb_band_t *bandinfos)
2268{
2269 uint_fast16_t bandno;
2270 uint_fast16_t gblbandno;
2271 uint_fast16_t rlvlno;
2272 jpc_tsfb_band_t *bandinfo;
2273 jpc_enc_tcmpt_t *tcmpt;
2274 uint_fast32_t prcno;
2275 jpc_enc_prc_t *prc;
2276
2277 tcmpt = rlvl->tcmpt;
2278 band->data = 0;
2279 band->prcs = 0;
2280 band->rlvl = rlvl;
2281
2282 /* Deduce the resolution level and band number. */
2283 rlvlno = rlvl - rlvl->tcmpt->rlvls;
2284 bandno = band - rlvl->bands;
2285 gblbandno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) + bandno + 1);
2286
2287 bandinfo = &bandinfos[gblbandno];
2288
2289if (bandinfo->xstart != bandinfo->xend && bandinfo->ystart != bandinfo->yend) {
2290 if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) {
2291 goto error;
2292 }
2293 if (jas_seq2d_bindsub(band->data, tcmpt->data, bandinfo->locxstart,
2294 bandinfo->locystart, bandinfo->locxend, bandinfo->locyend)) {
2295 goto error;
2296 }
2297 jas_seq2d_setshift(band->data, bandinfo->xstart, bandinfo->ystart);
2298}
2299 band->orient = bandinfo->orient;
2300 band->analgain = JPC_NOMINALGAIN(cp->tccp.qmfbid, tcmpt->numrlvls, rlvlno,
2301 band->orient);
2302 band->numbps = 0;
2303 band->absstepsize = 0;
2304 band->stepsize = 0;
2305 band->synweight = bandinfo->synenergywt;
2306
2307if (band->data) {
2308 if (!(band->prcs = jas_alloc2(rlvl->numprcs, sizeof(jpc_enc_prc_t)))) {
2309 goto error;
2310 }
2311 for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; ++prcno,
2312 ++prc) {
2313 prc->cblks = 0;
2314 prc->incltree = 0;
2315 prc->nlibtree = 0;
2316 prc->savincltree = 0;
2317 prc->savnlibtree = 0;
2318 prc->band = band;
2319 }
2320 for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; ++prcno,
2321 ++prc) {
2322 if (!prc_create(prc, band)) {
2323 goto error;
2324 }
2325 }
2326}
2327
2328 return band;
2329
2330error:
2331 band_destroy(band);
2332 return 0;
2333}
2334
2335/* Note: Since jpc_enc_band_t objects are created in-place, they might
2336potentially be destroyed multiple times at different levels in the call
2337chain. So, destroyed subobjects must be marked as destroyed to prevent
2338problems such as double frees. */
2339static void band_destroy(jpc_enc_band_t *band)
2340{
2341 jpc_enc_prc_t *prc;
2342 jpc_enc_rlvl_t *rlvl;
2343 uint_fast32_t prcno;
2344
2345 if (band->prcs) {
2346 rlvl = band->rlvl;
2347 for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs;
2348 ++prcno, ++prc) {
2349 prc_destroy(prc);
2350 }
2351 jas_free(band->prcs);
2352 band->prcs = NULL;
2353 }
2354 if (band->data) {
2355 jas_seq2d_destroy(band->data);
2356 band->data = NULL;
2357 }
2358}
2359
2360/* Note: This constructor creates the object in place. */
2361static jpc_enc_prc_t *prc_create(jpc_enc_prc_t *prc, jpc_enc_band_t *band)
2362{
2363 uint_fast32_t prcno;
2364 uint_fast32_t prcxind;
2365 uint_fast32_t prcyind;
2366 uint_fast32_t cbgtlx;
2367 uint_fast32_t cbgtly;
2368 uint_fast32_t tlprctlx;
2369 uint_fast32_t tlprctly;
2370 uint_fast32_t tlcbgtlx;
2371 uint_fast32_t tlcbgtly;
2372 uint_fast16_t rlvlno;
2373 jpc_enc_rlvl_t *rlvl;
2374 uint_fast32_t tlcblktlx;
2375 uint_fast32_t tlcblktly;
2376 uint_fast32_t brcblkbrx;
2377 uint_fast32_t brcblkbry;
2378 uint_fast32_t cblkno;
2379 jpc_enc_cblk_t *cblk;
2380 jpc_enc_tcmpt_t *tcmpt;
2381
2382 prc->cblks = 0;
2383 prc->incltree = 0;
2384 prc->savincltree = 0;
2385 prc->nlibtree = 0;
2386 prc->savnlibtree = 0;
2387
2388 rlvl = band->rlvl;
2389 tcmpt = rlvl->tcmpt;
2390 rlvlno = rlvl - tcmpt->rlvls;
2391 prcno = prc - band->prcs;
2392 prcxind = prcno % rlvl->numhprcs;
2393 prcyind = prcno / rlvl->numhprcs;
2394 prc->band = band;
2395
2396 tlprctlx = JPC_FLOORTOMULTPOW2(rlvl->tlx, rlvl->prcwidthexpn);
2397 tlprctly = JPC_FLOORTOMULTPOW2(rlvl->tly, rlvl->prcheightexpn);
2398 if (!rlvlno) {
2399 tlcbgtlx = tlprctlx;
2400 tlcbgtly = tlprctly;
2401 } else {
2402 tlcbgtlx = JPC_CEILDIVPOW2(tlprctlx, 1);
2403 tlcbgtly = JPC_CEILDIVPOW2(tlprctly, 1);
2404 }
2405
2406 /* Compute the coordinates of the top-left and bottom-right
2407 corners of the precinct. */
2408 cbgtlx = tlcbgtlx + (prcxind << rlvl->cbgwidthexpn);
2409 cbgtly = tlcbgtly + (prcyind << rlvl->cbgheightexpn);
2410 prc->tlx = JAS_MAX(jas_seq2d_xstart(band->data), (jas_matind_t)cbgtlx);
2411 prc->tly = JAS_MAX(jas_seq2d_ystart(band->data), (jas_matind_t)cbgtly);
2412 prc->brx = JAS_MIN(jas_seq2d_xend(band->data), (jas_matind_t)(cbgtlx +
2413 (1 << rlvl->cbgwidthexpn)));
2414 prc->bry = JAS_MIN(jas_seq2d_yend(band->data), (jas_matind_t)(cbgtly +
2415 (1 << rlvl->cbgheightexpn)));
2416
2417 if (prc->tlx < prc->brx && prc->tly < prc->bry) {
2418 /* The precinct contains at least one code block. */
2419
2420 tlcblktlx = JPC_FLOORTOMULTPOW2(prc->tlx, rlvl->cblkwidthexpn);
2421 tlcblktly = JPC_FLOORTOMULTPOW2(prc->tly, rlvl->cblkheightexpn);
2422 brcblkbrx = JPC_CEILTOMULTPOW2(prc->brx, rlvl->cblkwidthexpn);
2423 brcblkbry = JPC_CEILTOMULTPOW2(prc->bry, rlvl->cblkheightexpn);
2424 prc->numhcblks = JPC_FLOORDIVPOW2(brcblkbrx - tlcblktlx,
2425 rlvl->cblkwidthexpn);
2426 prc->numvcblks = JPC_FLOORDIVPOW2(brcblkbry - tlcblktly,
2427 rlvl->cblkheightexpn);
2428 prc->numcblks = prc->numhcblks * prc->numvcblks;
2429
2430 if (!(prc->incltree = jpc_tagtree_create(prc->numhcblks,
2431 prc->numvcblks))) {
2432 goto error;
2433 }
2434 if (!(prc->nlibtree = jpc_tagtree_create(prc->numhcblks,
2435 prc->numvcblks))) {
2436 goto error;
2437 }
2438 if (!(prc->savincltree = jpc_tagtree_create(prc->numhcblks,
2439 prc->numvcblks))) {
2440 goto error;
2441 }
2442 if (!(prc->savnlibtree = jpc_tagtree_create(prc->numhcblks,
2443 prc->numvcblks))) {
2444 goto error;
2445 }
2446
2447 if (!(prc->cblks = jas_alloc2(prc->numcblks, sizeof(jpc_enc_cblk_t)))) {
2448 goto error;
2449 }
2450 for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
2451 ++cblkno, ++cblk) {
2452 cblk->passes = 0;
2453 cblk->stream = 0;
2454 cblk->mqenc = 0;
2455 cblk->data = 0;
2456 cblk->flags = 0;
2457 cblk->prc = prc;
2458 }
2459 for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
2460 ++cblkno, ++cblk) {
2461 if (!cblk_create(cblk, prc)) {
2462 goto error;
2463 }
2464 }
2465 } else {
2466 /* The precinct does not contain any code blocks. */
2467 prc->tlx = prc->brx;
2468 prc->tly = prc->bry;
2469 prc->numcblks = 0;
2470 prc->numhcblks = 0;
2471 prc->numvcblks = 0;
2472 prc->cblks = 0;
2473 prc->incltree = 0;
2474 prc->nlibtree = 0;
2475 prc->savincltree = 0;
2476 prc->savnlibtree = 0;
2477 }
2478
2479 return prc;
2480
2481error:
2482 prc_destroy(prc);
2483 return 0;
2484}
2485
2486/* Note: Since jpc_enc_prc_t objects are created in-place, they might
2487potentially be destroyed multiple times at different levels in the call
2488chain. So, destroyed subobjects must be marked as destroyed to prevent
2489problems such as double frees. */
2490static void prc_destroy(jpc_enc_prc_t *prc)
2491{
2492 jpc_enc_cblk_t *cblk;
2493 uint_fast32_t cblkno;
2494
2495 if (prc->cblks) {
2496 for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
2497 ++cblkno, ++cblk) {
2498 cblk_destroy(cblk);
2499 }
2500 jas_free(prc->cblks);
2501 prc->cblks = NULL;
2502 }
2503 if (prc->incltree) {
2504 jpc_tagtree_destroy(prc->incltree);
2505 prc->incltree = NULL;
2506 }
2507 if (prc->nlibtree) {
2508 jpc_tagtree_destroy(prc->nlibtree);
2509 prc->nlibtree = NULL;
2510 }
2511 if (prc->savincltree) {
2512 jpc_tagtree_destroy(prc->savincltree);
2513 prc->savincltree = NULL;
2514 }
2515 if (prc->savnlibtree) {
2516 jpc_tagtree_destroy(prc->savnlibtree);
2517 prc->savnlibtree = NULL;
2518 }
2519}
2520
2521/* Note: This constructor creates the object in place. */
2522static jpc_enc_cblk_t *cblk_create(jpc_enc_cblk_t *cblk,
2523 jpc_enc_prc_t *prc)
2524{
2525 jpc_enc_band_t *band;
2526 uint_fast32_t cblktlx;
2527 uint_fast32_t cblktly;
2528 uint_fast32_t cblkbrx;
2529 uint_fast32_t cblkbry;
2530 jpc_enc_rlvl_t *rlvl;
2531 uint_fast32_t cblkxind;
2532 uint_fast32_t cblkyind;
2533 uint_fast32_t cblkno;
2534 uint_fast32_t tlcblktlx;
2535 uint_fast32_t tlcblktly;
2536
2537 cblkno = cblk - prc->cblks;
2538 cblkxind = cblkno % prc->numhcblks;
2539 cblkyind = cblkno / prc->numhcblks;
2540 rlvl = prc->band->rlvl;
2541 cblk->prc = prc;
2542
2543 cblk->numpasses = 0;
2544 cblk->passes = 0;
2545 cblk->numencpasses = 0;
2546 cblk->numimsbs = 0;
2547 cblk->numlenbits = 0;
2548 cblk->stream = 0;
2549 cblk->mqenc = 0;
2550 cblk->flags = 0;
2551 cblk->numbps = 0;
2552 cblk->curpass = 0;
2553 cblk->data = 0;
2554 cblk->savedcurpass = 0;
2555 cblk->savednumlenbits = 0;
2556 cblk->savednumencpasses = 0;
2557
2558 band = prc->band;
2559 tlcblktlx = JPC_FLOORTOMULTPOW2(prc->tlx, rlvl->cblkwidthexpn);
2560 tlcblktly = JPC_FLOORTOMULTPOW2(prc->tly, rlvl->cblkheightexpn);
2561 cblktlx = JAS_MAX(tlcblktlx + (cblkxind << rlvl->cblkwidthexpn), prc->tlx);
2562 cblktly = JAS_MAX(tlcblktly + (cblkyind << rlvl->cblkheightexpn), prc->tly);
2563 cblkbrx = JAS_MIN(tlcblktlx + ((cblkxind + 1) << rlvl->cblkwidthexpn),
2564 prc->brx);
2565 cblkbry = JAS_MIN(tlcblktly + ((cblkyind + 1) << rlvl->cblkheightexpn),
2566 prc->bry);
2567
2568 assert(cblktlx < cblkbrx && cblktly < cblkbry);
2569 if (!(cblk->data = jas_seq2d_create(0, 0, 0, 0))) {
2570 goto error;
2571 }
2572 if (jas_seq2d_bindsub(cblk->data, band->data, cblktlx, cblktly, cblkbrx, cblkbry)) {
2573 goto error;
2574 }
2575
2576 return cblk;
2577
2578error:
2579 cblk_destroy(cblk);
2580 return 0;
2581}
2582
2583/* Note: Since jpc_enc_cblk_t objects are created in-place, they might
2584potentially be destroyed multiple times at different levels in the call
2585chain. So, destroyed subobjects must be marked as destroyed to prevent
2586problems such as double frees. */
2587static void cblk_destroy(jpc_enc_cblk_t *cblk)
2588{
2589 uint_fast16_t passno;
2590 jpc_enc_pass_t *pass;
2591 if (cblk->passes) {
2592 for (passno = 0, pass = cblk->passes; passno < cblk->numpasses;
2593 ++passno, ++pass) {
2594 pass_destroy(pass);
2595 }
2596 jas_free(cblk->passes);
2597 cblk->passes = NULL;
2598 }
2599 if (cblk->stream) {
2600 jas_stream_close(cblk->stream);
2601 cblk->stream = NULL;
2602 }
2603 if (cblk->mqenc) {
2604 jpc_mqenc_destroy(cblk->mqenc);
2605 cblk->mqenc = NULL;
2606 }
2607 if (cblk->data) {
2608 jas_seq2d_destroy(cblk->data);
2609 cblk->data = NULL;
2610 }
2611 if (cblk->flags) {
2612 jas_seq2d_destroy(cblk->flags);
2613 cblk->flags = NULL;
2614 }
2615}
2616
2617static void pass_destroy(jpc_enc_pass_t *pass)
2618{
2619 /* XXX - need to free resources here */
2620 JAS_UNUSED(pass);
2621}
2622
2623void jpc_enc_dump(jpc_enc_t *enc)
2624{
2625 jpc_enc_tile_t *tile;
2626 jpc_enc_tcmpt_t *tcmpt;
2627 jpc_enc_rlvl_t *rlvl;
2628 jpc_enc_band_t *band;
2629 jpc_enc_prc_t *prc;
2630 jpc_enc_cblk_t *cblk;
2631 uint_fast16_t cmptno;
2632 uint_fast16_t rlvlno;
2633 uint_fast16_t bandno;
2634 uint_fast32_t prcno;
2635 uint_fast32_t cblkno;
2636
2637 tile = enc->curtile;
2638
2639 for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < tile->numtcmpts; ++cmptno,
2640 ++tcmpt) {
2641 jas_loginfof(" tcmpt %5d %5d %5d %5d\n", jas_seq2d_xstart(tcmpt->data), jas_seq2d_ystart(tcmpt->data), jas_seq2d_xend(tcmpt->data), jas_seq2d_yend(tcmpt->data));
2642 for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
2643 ++rlvlno, ++rlvl) {
2644 jas_loginfof(" rlvl %5d %5d %5d %5d\n", rlvl->tlx, rlvl->tly, rlvl->brx, rlvl->bry);
2645 for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
2646 ++bandno, ++band) {
2647 if (!band->data) {
2648 continue;
2649 }
2650 jas_loginfof(" band %5d %5d %5d %5d\n", jas_seq2d_xstart(band->data), jas_seq2d_ystart(band->data), jas_seq2d_xend(band->data), jas_seq2d_yend(band->data));
2651 for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs;
2652 ++prcno, ++prc) {
2653 jas_loginfof(" prc %5d %5d %5d %5d (%5d %5d)\n", prc->tlx, prc->tly, prc->brx, prc->bry, prc->brx - prc->tlx, prc->bry - prc->tly);
2654 if (!prc->cblks) {
2655 continue;
2656 }
2657 for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
2658 ++cblkno, ++cblk) {
2659 jas_loginfof(" cblk %5d %5d %5d %5d\n", jas_seq2d_xstart(cblk->data), jas_seq2d_ystart(cblk->data), jas_seq2d_xend(cblk->data), jas_seq2d_yend(cblk->data));
2660 }
2661 }
2662 }
2663 }
2664 }
2665}
jpc_enc.h+650−0
@@ -0,0 +1,650 @@
1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 * British Columbia.
4 * Copyright (c) 2001-2002 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64/*
65 * $Id$
66 */
67
68#ifndef JPC_ENC_H
69#define JPC_ENC_H
70
71/******************************************************************************\
72* Includes.
73\******************************************************************************/
74
75#include "jasper/jas_image.h"
76#include "jasper/jas_seq.h"
77#include "jasper/jas_stream.h"
78
79#include "jpc_cod.h"
80#include "jpc_t1cod.h"
81#include "jpc_t2cod.h"
82#include "jpc_mqenc.h"
83#include "jpc_tagtree.h"
84#include "jpc_cs.h"
85#include "jpc_fix.h"
86#include "jpc_flt.h"
87#include "jpc_tsfb.h"
88
89/******************************************************************************\
90* Constants.
91\******************************************************************************/
92
93/* The number of bits used in various lookup tables. */
94#define JPC_NUMEXTRABITS JPC_NMSEDEC_FRACBITS
95
96/* An invalid R-D slope value. */
97#define JPC_BADRDSLOPE (-1)
98
99/******************************************************************************\
100* Coding parameters types.
101\******************************************************************************/
102
103/* Per-component coding paramters. */
104
105typedef struct {
106
107 /* The horizontal sampling period. */
108 uint_fast8_t sampgrdstepx;
109
110 /* The vertical sampling period. */
111 uint_fast8_t sampgrdstepy;
112
113 /* The sample alignment horizontal offset. */
114 uint_fast8_t sampgrdsubstepx;
115
116 /* The sample alignment vertical offset. */
117 uint_fast8_t sampgrdsubstepy;
118
119 /* The precision of the samples. */
120 uint_fast8_t prec;
121
122 /* The signedness of the samples. */
123 bool sgnd;
124
125 /* The number of step sizes. */
126 uint_fast16_t numstepsizes;
127
128 /* The quantizer step sizes. */
129 uint_fast16_t stepsizes[JPC_MAXBANDS];
130
131} jpc_enc_ccp_t;
132
133/* Per-tile coding parameters. */
134
135typedef struct {
136
137 /* The coding mode. */
138 bool intmode;
139
140 /* The coding style (i.e., SOP, EPH). */
141 uint_fast8_t csty;
142
143 /* The progression order. */
144 uint_fast8_t prg;
145
146 /* The multicomponent transform. */
147 uint_fast8_t mctid;
148
149 /* The number of layers. */
150 uint_fast16_t numlyrs;
151
152 /* The normalized bit rates associated with the various
153 intermediate layers. */
154 jpc_fix_t *ilyrrates;
155
156} jpc_enc_tcp_t;
157
158/* Per tile-component coding parameters. */
159
160typedef struct {
161
162 /* The coding style (i.e., explicit precinct sizes). */
163 uint_fast8_t csty;
164
165 /* The maximum number of resolution levels allowed. */
166 uint_fast8_t maxrlvls;
167
168 /* The exponent for the nominal code block width. */
169 uint_fast16_t cblkwidthexpn;
170
171 /* The exponent for the nominal code block height. */
172 uint_fast16_t cblkheightexpn;
173
174 /* The code block style parameters (e.g., lazy, terminate all,
175 segmentation symbols, causal, reset probability models). */
176 uint_fast8_t cblksty;
177
178 /* The QMFB. */
179 uint_fast8_t qmfbid;
180
181 /* The precinct width values. */
182 uint_fast16_t prcwidthexpns[JPC_MAXRLVLS];
183
184 /* The precinct height values. */
185 uint_fast16_t prcheightexpns[JPC_MAXRLVLS];
186
187 /* The number of guard bits. */
188 uint_fast8_t numgbits;
189
190} jpc_enc_tccp_t;
191
192/* Coding parameters. */
193
194typedef struct {
195
196 /* The debug level. */
197 int debug;
198
199 /* The horizontal offset from the origin of the reference grid to the
200 left edge of the image area. */
201 uint_fast32_t imgareatlx;
202
203 /* The vertical offset from the origin of the reference grid to the
204 top edge of the image area. */
205 uint_fast32_t imgareatly;
206
207 /* The horizontal offset from the origin of the reference grid to the
208 right edge of the image area (plus one). */
209 uint_fast32_t refgrdwidth;
210
211 /* The vertical offset from the origin of the reference grid to the
212 bottom edge of the image area (plus one). */
213 uint_fast32_t refgrdheight;
214
215 /* The horizontal offset from the origin of the tile grid to the
216 origin of the reference grid. */
217 uint_fast32_t tilegrdoffx;
218
219 /* The vertical offset from the origin of the tile grid to the
220 origin of the reference grid. */
221 uint_fast32_t tilegrdoffy;
222
223 /* The nominal tile width in units of the image reference grid. */
224 uint_fast32_t tilewidth;
225
226 /* The nominal tile height in units of the image reference grid. */
227 uint_fast32_t tileheight;
228
229 /* The number of tiles spanning the image area in the horizontal
230 direction. */
231 uint_fast32_t numhtiles;
232
233 /* The number of tiles spanning the image area in the vertical
234 direction. */
235 uint_fast32_t numvtiles;
236
237 /* The number of tiles. */
238 uint_fast32_t numtiles;
239
240 /* The number of components. */
241 uint_fast16_t numcmpts;
242
243 /* The per-component coding parameters. */
244 jpc_enc_ccp_t *ccps;
245
246 /* The per-tile coding parameters. */
247 jpc_enc_tcp_t tcp;
248
249 /* The per-tile-component coding parameters. */
250 jpc_enc_tccp_t tccp;
251
252 /* The target code stream length in bytes. */
253 uint_fast32_t totalsize;
254
255 /* The raw (i.e., uncompressed) size of the image in bytes. */
256 uint_fast32_t rawsize;
257
258} jpc_enc_cp_t;
259
260/******************************************************************************\
261* Encoder class.
262\******************************************************************************/
263
264/* Encoder per-coding-pass state information. */
265
266typedef struct {
267
268 /* The starting offset for this pass. */
269 int start;
270
271 /* The ending offset for this pass. */
272 int end;
273
274 /* The type of data in this pass (i.e., MQ or raw). */
275 enum jpc_segtype type;
276
277 /* Flag indicating that this pass is terminated. */
278 int term;
279
280 /* The entropy coder state after coding this pass. */
281 jpc_mqencstate_t mqencstate;
282
283 /* The layer to which this pass has been assigned. */
284 unsigned lyrno;
285
286 /* The R-D slope for this pass. */
287 jpc_flt_t rdslope;
288
289 /* The weighted MSE reduction associated with this pass. */
290 jpc_flt_t wmsedec;
291
292 /* The cumulative weighted MSE reduction. */
293 jpc_flt_t cumwmsedec;
294
295 /* The normalized MSE reduction. */
296 long nmsedec;
297
298} jpc_enc_pass_t;
299
300/* Encoder per-code-block state information. */
301
302typedef struct {
303
304 /* The number of passes. */
305 unsigned numpasses;
306
307 /* The per-pass information. */
308 jpc_enc_pass_t *passes;
309
310 /* The number of passes encoded so far. */
311 int numencpasses;
312
313 /* The number of insignificant MSBs. */
314 int numimsbs;
315
316 /* The number of bits used to encode pass data lengths. */
317 int numlenbits;
318
319 /* The byte stream for this code block. */
320 jas_stream_t *stream;
321
322 /* The entropy encoder. */
323 jpc_mqenc_t *mqenc;
324
325 /* The data for this code block. */
326 jas_matrix_t *data;
327
328 /* The state for this code block. */
329 jas_matrix_t *flags;
330
331 /* The number of bit planes required for this code block. */
332 int numbps;
333
334 /* The next pass to be encoded. */
335 jpc_enc_pass_t *curpass;
336
337 /* The per-code-block-group state information. */
338 struct jpc_enc_prc_s *prc;
339
340 /* The saved current pass. */
341 /* This is used by the rate control code. */
342 jpc_enc_pass_t *savedcurpass;
343
344 /* The saved length indicator size. */
345 /* This is used by the rate control code. */
346 int savednumlenbits;
347
348 /* The saved number of encoded passes. */
349 /* This is used by the rate control code. */
350 int savednumencpasses;
351
352} jpc_enc_cblk_t;
353
354/* Encoder per-code-block-group state information. */
355
356typedef struct jpc_enc_prc_s {
357
358 /* The x-coordinate of the top-left corner of the precinct. */
359 uint_fast32_t tlx;
360
361 /* The y-coordinate of the top-left corner of the precinct. */
362 uint_fast32_t tly;
363
364 /* The x-coordinate of the bottom-right corner of the precinct
365 (plus one). */
366 uint_fast32_t brx;
367
368 /* The y-coordinate of the bottom-right corner of the precinct
369 (plus one). */
370 uint_fast32_t bry;
371
372 /* The number of code blocks spanning the precinct in the horizontal
373 direction. */
374 int numhcblks;
375
376 /* The number of code blocks spanning the precinct in the vertical
377 direction. */
378 int numvcblks;
379
380 /* The total number of code blocks. */
381 unsigned numcblks;
382
383 /* The per-code-block information. */
384 jpc_enc_cblk_t *cblks;
385
386 /* The inclusion tag tree. */
387 jpc_tagtree_t *incltree;
388
389 /* The insignifcant MSBs tag tree. */
390 jpc_tagtree_t *nlibtree;
391
392 /* The per-band information. */
393 struct jpc_enc_band_s *band;
394
395 /* The saved inclusion tag tree. */
396 /* This is used by rate control. */
397 jpc_tagtree_t *savincltree;
398
399 /* The saved leading-insignificant-bit-planes tag tree. */
400 /* This is used by rate control. */
401 jpc_tagtree_t *savnlibtree;
402
403} jpc_enc_prc_t;
404
405/* Encoder per-band state information. */
406
407typedef struct jpc_enc_band_s {
408
409 /* The per precinct information. */
410 jpc_enc_prc_t *prcs;
411
412 /* The coefficient data for this band. */
413 jas_matrix_t *data;
414
415 /* The orientation of this band (i.e., LL, LH, HL, or HH). */
416 enum jpc_tsfb_orient orient;
417
418 /* The number of bit planes associated with this band. */
419 int numbps;
420
421 /* The quantizer step size. */
422 jpc_fix_t absstepsize;
423
424 /* The encoded quantizer step size. */
425 int stepsize;
426
427 /* The L2 norm of the synthesis basis functions associated with
428 this band. (The MCT is not considered in this value.) */
429 jpc_fix_t synweight;
430
431 /* The analysis gain for this band. */
432 int analgain;
433
434 /* The per-resolution-level information. */
435 struct jpc_enc_rlvl_s *rlvl;
436
437} jpc_enc_band_t;
438
439/* Encoder per-resolution-level state information. */
440
441typedef struct jpc_enc_rlvl_s {
442
443 /* The x-coordinate of the top-left corner of the tile-component
444 at this resolution. */
445 uint_fast32_t tlx;
446
447 /* The y-coordinate of the top-left corner of the tile-component
448 at this resolution. */
449 uint_fast32_t tly;
450
451 /* The x-coordinate of the bottom-right corner of the tile-component
452 at this resolution (plus one). */
453 uint_fast32_t brx;
454
455 /* The y-coordinate of the bottom-right corner of the tile-component
456 at this resolution (plus one). */
457 uint_fast32_t bry;
458
459 /* The exponent value for the nominal precinct width measured
460 relative to the associated LL band. */
461 int prcwidthexpn;
462
463 /* The exponent value for the nominal precinct height measured
464 relative to the associated LL band. */
465 int prcheightexpn;
466
467 /* The number of precincts spanning the resolution level in the
468 horizontal direction. */
469 int numhprcs;
470
471 /* The number of precincts spanning the resolution level in the
472 vertical direction. */
473 int numvprcs;
474
475 /* The total number of precincts. */
476 unsigned numprcs;
477
478 /* The exponent value for the nominal code block group width.
479 This quantity is associated with the next lower resolution level
480 (assuming that there is one). */
481 unsigned cbgwidthexpn;
482
483 /* The exponent value for the nominal code block group height.
484 This quantity is associated with the next lower resolution level
485 (assuming that there is one). */
486 unsigned cbgheightexpn;
487
488 /* The exponent value for the code block width. */
489 uint_fast16_t cblkwidthexpn;
490
491 /* The exponent value for the code block height. */
492 uint_fast16_t cblkheightexpn;
493
494 /* The number of bands associated with this resolution level. */
495 unsigned numbands;
496
497 /* The per-band information. */
498 jpc_enc_band_t *bands;
499
500 /* The parent tile-component. */
501 struct jpc_enc_tcmpt_s *tcmpt;
502
503} jpc_enc_rlvl_t;
504
505/* Encoder per-tile-component state information. */
506
507typedef struct jpc_enc_tcmpt_s {
508
509 /* The number of resolution levels. */
510 unsigned numrlvls;
511
512 /* The per-resolution-level information. */
513 jpc_enc_rlvl_t *rlvls;
514
515 /* The tile-component data. */
516 jas_matrix_t *data;
517
518 /* The QMFB. */
519 int qmfbid;
520
521 /* The number of bands. */
522 int numbands;
523
524 /* The TSFB. */
525 jpc_tsfb_t *tsfb;
526
527 /* The synthesis energy weight (for the MCT). */
528 jpc_fix_t synweight;
529
530 /* The precinct width exponents. */
531 int prcwidthexpns[JPC_MAXRLVLS];
532
533 /* The precinct height exponents. */
534 int prcheightexpns[JPC_MAXRLVLS];
535
536 /* The code block width exponent. */
537 int cblkwidthexpn;
538
539 /* The code block height exponent. */
540 int cblkheightexpn;
541
542 /* Coding style (i.e., explicit precinct sizes). */
543 int csty;
544
545 /* Code block style. */
546 int cblksty;
547
548 /* The number of quantizer step sizes. */
549 int numstepsizes;
550
551 /* The encoded quantizer step sizes. */
552 uint_fast16_t stepsizes[JPC_MAXBANDS];
553
554 /* The parent tile. */
555 struct jpc_enc_tile_s *tile;
556
557} jpc_enc_tcmpt_t;
558
559/* Encoder per-tile state information. */
560
561typedef struct jpc_enc_tile_s {

89 more lines aren’t shown here.

jpc_fix.h+28−15

This diff is large: its 68 lines aren’t shown here.

jpc_math.c+34−0

This diff is large: its 38 lines aren’t shown here.

jpc_math.h+8−0

This diff is large: its 15 lines aren’t shown here.

jpc_mqdec.c+22−4

This diff is large: its 45 lines aren’t shown here.

jpc_mqdec.h+7−0

This diff is large: its 14 lines aren’t shown here.

jpc_mqenc.c+386−0

This diff is large: its 387 lines aren’t shown here.

jpc_mqenc.h+217−0

This diff is large: its 218 lines aren’t shown here.

jpc_qmfb.c+131−141

This diff is large: its 522 lines aren’t shown here.

jpc_t1cod.c+18−15

This diff is large: its 103 lines aren’t shown here.

jpc_t1cod.h+2−0

This diff is large: its 9 lines aren’t shown here.

jpc_t1dec.c+19−17

This diff is large: its 99 lines aren’t shown here.

jpc_t1enc.c+895−0

This diff is large: its 896 lines aren’t shown here.

jpc_t1enc.h+86−0

This diff is large: its 87 lines aren’t shown here.

jpc_t2cod.c+153−53

This diff is large: its 340 lines aren’t shown here.

jpc_t2cod.h+6−0

This diff is large: its 11 lines aren’t shown here.

jpc_t2dec.c+47−21

This diff is large: its 250 lines aren’t shown here.

jpc_t2enc.c+656−0

This diff is large: its 657 lines aren’t shown here.

jpc_t2enc.h+105−0

This diff is large: its 106 lines aren’t shown here.

jpc_tagtree.c+21−6

This diff is large: its 52 lines aren’t shown here.

jpc_tagtree.h+3−0

This diff is large: its 8 lines aren’t shown here.

jpc_tsfb.c+9−4

This diff is large: its 48 lines aren’t shown here.

jpc_util.c+186−0

This diff is large: its 187 lines aren’t shown here.

jpc_util.h+82−0

This diff is large: its 83 lines aren’t shown here.

mklib+35−0

This diff is large: its 61 lines aren’t shown here.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t