/src/ghostpdl/base/gscscie.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* CIE color space management */ |
18 | | #include "math_.h" |
19 | | #include "gx.h" |
20 | | #include "gserrors.h" |
21 | | #include "gsstruct.h" |
22 | | #include "gsmatrix.h" /* for gscolor2.h */ |
23 | | #include "gxcspace.h" |
24 | | #include "gscolor2.h" /* for gs_set/currentcolorrendering */ |
25 | | #include "gsicc_manage.h" /* for gsicc_adjust_profile_rc */ |
26 | | #include "gxcie.h" |
27 | | #include "gxarith.h" |
28 | | #include "gxdevice.h" /* for gxcmap.h */ |
29 | | #include "gxcmap.h" |
30 | | #include "gzstate.h" |
31 | | #include "stream.h" |
32 | | |
33 | | /* ---------------- Color space definition ---------------- */ |
34 | | |
35 | | /* GC descriptors */ |
36 | | public_st_cie_common(); |
37 | | public_st_cie_common_elements(); |
38 | | private_st_cie_a(); |
39 | | private_st_cie_abc(); |
40 | | private_st_cie_def(); |
41 | | private_st_cie_defg(); |
42 | | |
43 | | /* Define the CIE color space types. */ |
44 | | |
45 | | /* CIEBasedDEFG */ |
46 | | gs_private_st_ptrs1(st_color_space_CIEDEFG, gs_color_space, |
47 | | "gs_color_space(CIEDEFG)", cs_CIEDEFG_enum_ptrs, cs_CIEDEFG_reloc_ptrs, |
48 | | params.defg); |
49 | | static cs_proc_final(gx_final_CIEDEFG); |
50 | | static cs_proc_serialize(gx_serialize_CIEDEFG); |
51 | | const gs_color_space_type gs_color_space_type_CIEDEFG = { |
52 | | gs_color_space_index_CIEDEFG, true, true, |
53 | | &st_color_space_CIEDEFG, gx_num_components_4, |
54 | | gx_init_CIE, gx_restrict_CIEDEFG, |
55 | | gx_concrete_space_CIE, |
56 | | gx_concretize_CIEDEFG, NULL, |
57 | | gx_remap_CIEDEFG, |
58 | | gx_install_CIE, |
59 | | gx_spot_colors_set_overprint, |
60 | | gx_final_CIEDEFG, gx_no_adjust_color_count, |
61 | | gx_serialize_CIEDEFG, |
62 | | gx_cspace_is_linear_default, gx_polarity_subtractive |
63 | | }; |
64 | | |
65 | | /* CIEBasedDEF */ |
66 | | gs_private_st_ptrs1(st_color_space_CIEDEF, gs_color_space, |
67 | | "gs_color_space(CIEDEF)", cs_CIEDEF_enum_ptrs, cs_CIEDEF_reloc_ptrs, |
68 | | params.def); |
69 | | static cs_proc_final(gx_final_CIEDEF); |
70 | | static cs_proc_serialize(gx_serialize_CIEDEF); |
71 | | const gs_color_space_type gs_color_space_type_CIEDEF = { |
72 | | gs_color_space_index_CIEDEF, true, true, |
73 | | &st_color_space_CIEDEF, gx_num_components_3, |
74 | | gx_init_CIE, gx_restrict_CIEDEF, |
75 | | gx_concrete_space_CIE, |
76 | | gx_concretize_CIEDEF, NULL, |
77 | | gx_remap_CIEDEF, |
78 | | gx_install_CIE, |
79 | | gx_spot_colors_set_overprint, |
80 | | gx_final_CIEDEF, gx_no_adjust_color_count, |
81 | | gx_serialize_CIEDEF, |
82 | | gx_cspace_is_linear_default, gx_polarity_subtractive |
83 | | }; |
84 | | |
85 | | /* CIEBasedABC */ |
86 | | gs_private_st_ptrs1(st_color_space_CIEABC, gs_color_space, |
87 | | "gs_color_space(CIEABC)", cs_CIEABC_enum_ptrs, cs_CIEABC_reloc_ptrs, |
88 | | params.abc); |
89 | | static cs_proc_final(gx_final_CIEABC); |
90 | | static cs_proc_serialize(gx_serialize_CIEABC); |
91 | | const gs_color_space_type gs_color_space_type_CIEABC = { |
92 | | gs_color_space_index_CIEABC, true, true, |
93 | | &st_color_space_CIEABC, gx_num_components_3, |
94 | | gx_init_CIE, gx_restrict_CIEABC, |
95 | | gx_concrete_space_CIE, |
96 | | gx_concretize_CIEABC, NULL, |
97 | | gx_remap_CIEABC, gx_install_CIE, |
98 | | gx_spot_colors_set_overprint, |
99 | | gx_final_CIEABC, gx_no_adjust_color_count, |
100 | | gx_serialize_CIEABC, |
101 | | gx_cspace_is_linear_default, gx_polarity_additive |
102 | | }; |
103 | | |
104 | | /* CIEBasedA */ |
105 | | gs_private_st_ptrs1(st_color_space_CIEA, gs_color_space, |
106 | | "gs_color_space(CIEA)", cs_CIEA_enum_ptrs, cs_CIEA_reloc_ptrs, |
107 | | params.a); |
108 | | static cs_proc_final(gx_final_CIEA); |
109 | | static cs_proc_serialize(gx_serialize_CIEA); |
110 | | const gs_color_space_type gs_color_space_type_CIEA = { |
111 | | gs_color_space_index_CIEA, true, true, |
112 | | &st_color_space_CIEA, gx_num_components_1, |
113 | | gx_init_CIE, gx_restrict_CIEA, |
114 | | gx_concrete_space_CIE, |
115 | | gx_concretize_CIEA, NULL, |
116 | | gx_remap_CIEA, |
117 | | gx_install_CIE, |
118 | | gx_spot_colors_set_overprint, |
119 | | gx_final_CIEA, gx_no_adjust_color_count, |
120 | | gx_serialize_CIEA, |
121 | | gx_cspace_is_linear_default, gx_polarity_additive |
122 | | }; |
123 | | |
124 | | /* Determine the concrete space underlying a CIEBased space. */ |
125 | | const gs_color_space * |
126 | | gx_concrete_space_CIE(const gs_color_space * pcs, const gs_gstate * pgs) |
127 | 0 | { |
128 | 0 | const gs_cie_render *pcie = pgs->cie_render; |
129 | |
|
130 | 0 | if (pcie == 0 || pcie->RenderTable.lookup.table == 0 || |
131 | 0 | pcie->RenderTable.lookup.m == 3 |
132 | 0 | ) { |
133 | 0 | return pgs->devicergb_cs; |
134 | 0 | } else { /* pcie->RenderTable.lookup.m == 4 */ |
135 | 0 | return pgs->devicecmyk_cs; |
136 | 0 | } |
137 | 0 | } |
138 | | |
139 | | /* Install a CIE space in the graphics state. */ |
140 | | /* We go through an extra level of procedure so that */ |
141 | | /* interpreters can substitute their own installer. */ |
142 | | /* This procedure is exported for the benefit of gsicc.c */ |
143 | | int |
144 | | gx_install_CIE(gs_color_space * pcs, gs_gstate * pgs) |
145 | 0 | { |
146 | 0 | return (*pcs->params.a->common.install_cspace) (pcs, pgs); |
147 | 0 | } |
148 | | |
149 | | /* Free params for a CIE color space */ |
150 | | static void |
151 | | gx_final_CIEDEFG(gs_color_space * pcs) |
152 | 0 | { |
153 | 0 | if (pcs->icc_equivalent != NULL) { |
154 | 0 | rc_decrement(pcs->icc_equivalent, "gx_final_CIEDEFG"); |
155 | 0 | pcs->icc_equivalent = NULL; |
156 | 0 | } |
157 | 0 | if (pcs->cmm_icc_profile_data != NULL) { |
158 | 0 | gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_final_CIEDEFG"); |
159 | 0 | pcs->cmm_icc_profile_data = NULL; |
160 | 0 | } |
161 | 0 | rc_decrement(pcs->params.defg, "gx_final_CIEDEFG"); |
162 | 0 | pcs->params.defg = NULL; |
163 | 0 | } |
164 | | |
165 | | static void |
166 | | gx_final_CIEDEF(gs_color_space * pcs) |
167 | 0 | { |
168 | 0 | if (pcs->icc_equivalent != NULL) { |
169 | 0 | rc_decrement(pcs->icc_equivalent,"gx_final_CIEDEF"); |
170 | 0 | pcs->icc_equivalent = NULL; |
171 | 0 | } |
172 | 0 | if (pcs->cmm_icc_profile_data != NULL) { |
173 | 0 | gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_final_CIEDEF"); |
174 | 0 | pcs->cmm_icc_profile_data = NULL; |
175 | 0 | } |
176 | 0 | rc_decrement(pcs->params.def, "gx_final_CIEDEF"); |
177 | 0 | pcs->params.def = NULL; |
178 | 0 | } |
179 | | |
180 | | static void |
181 | | gx_final_CIEABC(gs_color_space * pcs) |
182 | 0 | { |
183 | 0 | if (pcs->icc_equivalent != NULL) { |
184 | 0 | rc_decrement(pcs->icc_equivalent,"gx_final_CIEABC"); |
185 | 0 | pcs->icc_equivalent = NULL; |
186 | 0 | } |
187 | 0 | if (pcs->cmm_icc_profile_data != NULL) { |
188 | 0 | gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_final_CIEABC"); |
189 | 0 | pcs->cmm_icc_profile_data = NULL; |
190 | 0 | } |
191 | 0 | rc_decrement(pcs->params.abc, "gx_final_CIEABC"); |
192 | 0 | pcs->params.abc = NULL; |
193 | 0 | } |
194 | | |
195 | | static void |
196 | | gx_final_CIEA(gs_color_space * pcs) |
197 | 0 | { |
198 | 0 | if (pcs->icc_equivalent != NULL) { |
199 | 0 | rc_decrement(pcs->icc_equivalent,"gx_final_CIEA"); |
200 | 0 | pcs->icc_equivalent = NULL; |
201 | 0 | } |
202 | 0 | if (pcs->cmm_icc_profile_data != NULL) { |
203 | 0 | gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_final_CIEA"); |
204 | 0 | pcs->cmm_icc_profile_data = NULL; |
205 | 0 | } |
206 | 0 | rc_decrement(pcs->params.a, "gx_adjust_cspace_CIEA"); |
207 | 0 | pcs->params.a = NULL; |
208 | 0 | } |
209 | | |
210 | | /* ---------------- Procedures ---------------- */ |
211 | | |
212 | | /* ------ Internal initializers ------ */ |
213 | | |
214 | | /* |
215 | | * Set up the default values for the CIE parameters that are common to |
216 | | * all CIE color spaces. |
217 | | * |
218 | | * There is no default for the white point, so it is set equal to the |
219 | | * black point. If anyone actually uses the color space in that form, |
220 | | * the results are likely to be unsatisfactory. |
221 | | * |
222 | | * This procedure is exported for the benefit of gsicc.c. |
223 | | */ |
224 | | void |
225 | | gx_set_common_cie_defaults(gs_cie_common * pcommon, void *client_data) |
226 | 0 | { |
227 | 0 | pcommon->RangeLMN = Range3_default; |
228 | 0 | pcommon->DecodeLMN = DecodeLMN_default; |
229 | 0 | pcommon->MatrixLMN = Matrix3_default; |
230 | 0 | pcommon->points.WhitePoint = BlackPoint_default; |
231 | 0 | pcommon->points.BlackPoint = BlackPoint_default; |
232 | 0 | pcommon->client_data = client_data; |
233 | 0 | } |
234 | | |
235 | | /* |
236 | | * Set defaults for a CIEBasedABC color space. This is also used for |
237 | | * CIEBasedDEF and CIEBasedDEFG color spaces. |
238 | | */ |
239 | | static void |
240 | | set_cie_abc_defaults(gs_cie_abc * pabc, void *client_data) |
241 | 0 | { |
242 | 0 | gx_set_common_cie_defaults(&pabc->common, client_data); |
243 | 0 | pabc->RangeABC = Range3_default; |
244 | 0 | pabc->DecodeABC = DecodeABC_default; |
245 | 0 | pabc->MatrixABC = Matrix3_default; |
246 | 0 | } |
247 | | |
248 | | /* |
249 | | * Set up a default color lookup table for a CIEBasedDEF[G] space. There is |
250 | | * no specified default for this structure, so the values used here (aside |
251 | | * from the input and output component numbers) are intended only to make |
252 | | * the system fail in a predictable manner. |
253 | | */ |
254 | | static void |
255 | | set_ctbl_defaults(gx_color_lookup_table * plktblp, int num_comps) |
256 | 0 | { |
257 | 0 | int i; |
258 | |
|
259 | 0 | plktblp->n = num_comps; |
260 | 0 | plktblp->m = 3; /* always output CIE ABC */ |
261 | 0 | for (i = 0; i < countof(plktblp->dims); i++) |
262 | 0 | plktblp->dims[i] = 0; |
263 | 0 | plktblp->table = 0; |
264 | 0 | } |
265 | | |
266 | | /* |
267 | | * Allocate a color space and its parameter structure. |
268 | | * Return 0 if VMerror, otherwise the parameter structure. |
269 | | * |
270 | | * This is exported for the benefit of gsicc.c |
271 | | */ |
272 | | void * |
273 | | gx_build_cie_space(gs_color_space ** ppcspace, |
274 | | const gs_color_space_type * pcstype, |
275 | | gs_memory_type_ptr_t stype, gs_memory_t * pmem) |
276 | 0 | { |
277 | 0 | gs_color_space *pcspace = gs_cspace_alloc(pmem, pcstype); |
278 | 0 | gs_cie_common_elements_t *pdata; |
279 | |
|
280 | 0 | if (pcspace == NULL) |
281 | 0 | return NULL; |
282 | 0 | rc_alloc_struct_1(pdata, gs_cie_common_elements_t, stype, pmem, |
283 | 0 | { |
284 | 0 | gs_free_object(pmem, pcspace, "gx_build_cie_space"); |
285 | 0 | return 0; |
286 | 0 | } |
287 | 0 | , |
288 | 0 | "gx_build_cie_space(data)"); |
289 | 0 | *ppcspace = pcspace; |
290 | 0 | return (void *)pdata; |
291 | 0 | } |
292 | | |
293 | | /* ------ Constructors ------ */ |
294 | | |
295 | | int |
296 | | gs_cspace_build_CIEA(gs_color_space ** ppcspace, void *client_data, |
297 | | gs_memory_t * pmem) |
298 | 0 | { |
299 | 0 | gs_cie_a *pciea = |
300 | 0 | gx_build_cie_space(ppcspace, &gs_color_space_type_CIEA, &st_cie_a, pmem); |
301 | |
|
302 | 0 | if (pciea == 0) |
303 | 0 | return_error(gs_error_VMerror); |
304 | | |
305 | 0 | gx_set_common_cie_defaults(&pciea->common, client_data); |
306 | 0 | pciea->common.install_cspace = gx_install_CIEA; |
307 | 0 | pciea->RangeA = RangeA_default; |
308 | 0 | pciea->DecodeA = DecodeA_default; |
309 | 0 | pciea->MatrixA = MatrixA_default; |
310 | |
|
311 | 0 | (*ppcspace)->params.a = pciea; |
312 | 0 | return 0; |
313 | 0 | } |
314 | | |
315 | | int |
316 | | gs_cspace_build_CIEABC(gs_color_space ** ppcspace, void *client_data, |
317 | | gs_memory_t * pmem) |
318 | 0 | { |
319 | 0 | gs_cie_abc *pabc = |
320 | 0 | gx_build_cie_space(ppcspace, &gs_color_space_type_CIEABC, &st_cie_abc, |
321 | 0 | pmem); |
322 | |
|
323 | 0 | if (pabc == 0) |
324 | 0 | return_error(gs_error_VMerror); |
325 | | |
326 | 0 | set_cie_abc_defaults(pabc, client_data); |
327 | 0 | pabc->common.install_cspace = gx_install_CIEABC; |
328 | |
|
329 | 0 | (*ppcspace)->params.abc = pabc; |
330 | 0 | return 0; |
331 | 0 | } |
332 | | |
333 | | int |
334 | | gs_cspace_build_CIEDEF(gs_color_space ** ppcspace, void *client_data, |
335 | | gs_memory_t * pmem) |
336 | 0 | { |
337 | 0 | gs_cie_def *pdef = |
338 | 0 | gx_build_cie_space(ppcspace, &gs_color_space_type_CIEDEF, &st_cie_def, |
339 | 0 | pmem); |
340 | |
|
341 | 0 | if (pdef == 0) |
342 | 0 | return_error(gs_error_VMerror); |
343 | | |
344 | 0 | set_cie_abc_defaults((gs_cie_abc *) pdef, client_data); |
345 | 0 | pdef->common.install_cspace = gx_install_CIEDEF; |
346 | 0 | pdef->RangeDEF = Range3_default; |
347 | 0 | pdef->DecodeDEF = DecodeDEF_default; |
348 | 0 | pdef->RangeHIJ = Range3_default; |
349 | 0 | set_ctbl_defaults(&pdef->Table, 3); |
350 | |
|
351 | 0 | (*ppcspace)->params.def = pdef; |
352 | 0 | return 0; |
353 | 0 | } |
354 | | |
355 | | int |
356 | | gs_cspace_build_CIEDEFG(gs_color_space ** ppcspace, void *client_data, |
357 | | gs_memory_t * pmem) |
358 | 0 | { |
359 | 0 | gs_cie_defg *pdefg = |
360 | 0 | gx_build_cie_space(ppcspace, &gs_color_space_type_CIEDEFG, &st_cie_defg, |
361 | 0 | pmem); |
362 | |
|
363 | 0 | if (pdefg == 0) |
364 | 0 | return_error(gs_error_VMerror); |
365 | | |
366 | 0 | set_cie_abc_defaults((gs_cie_abc *) pdefg, client_data); |
367 | 0 | pdefg->common.install_cspace = gx_install_CIEDEFG; |
368 | 0 | pdefg->RangeDEFG = Range4_default; |
369 | 0 | pdefg->DecodeDEFG = DecodeDEFG_default; |
370 | 0 | pdefg->RangeHIJK = Range4_default; |
371 | 0 | set_ctbl_defaults(&pdefg->Table, 4); |
372 | |
|
373 | 0 | (*ppcspace)->params.defg = pdefg; |
374 | 0 | return 0; |
375 | 0 | } |
376 | | |
377 | | /* ------ Accessors ------ */ |
378 | | |
379 | | int |
380 | | gs_cie_defx_set_lookup_table(gs_color_space * pcspace, int *pdims, |
381 | | const gs_const_string * ptable) |
382 | 0 | { |
383 | 0 | gx_color_lookup_table *plktblp; |
384 | |
|
385 | 0 | switch (gs_color_space_get_index(pcspace)) { |
386 | 0 | case gs_color_space_index_CIEDEF: |
387 | 0 | plktblp = &pcspace->params.def->Table; |
388 | 0 | break; |
389 | 0 | case gs_color_space_index_CIEDEFG: |
390 | 0 | plktblp = &pcspace->params.defg->Table; |
391 | 0 | plktblp->dims[3] = pdims[3]; |
392 | 0 | break; |
393 | 0 | default: |
394 | 0 | return_error(gs_error_rangecheck); |
395 | 0 | } |
396 | | |
397 | 0 | plktblp->dims[0] = pdims[0]; |
398 | 0 | plktblp->dims[1] = pdims[1]; |
399 | 0 | plktblp->dims[2] = pdims[2]; |
400 | 0 | plktblp->table = ptable; |
401 | 0 | return 0; |
402 | 0 | } |
403 | | |
404 | | /* ---------------- Serialization. -------------------------------- */ |
405 | | |
406 | | static int |
407 | | gx_serialize_cie_cache(const cie_cache_floats *c, stream * s) |
408 | 0 | { /* p->DecodeA : */ |
409 | 0 | const uint cache_size = count_of(c->values); |
410 | 0 | uint n; |
411 | 0 | int code; |
412 | |
|
413 | 0 | code = sputs(s, (const byte *)&c->params.is_identity, sizeof(c->params.is_identity), &n); |
414 | 0 | if (code < 0) |
415 | 0 | return_error(gs_error_ioerror); |
416 | 0 | if (c->params.is_identity) |
417 | 0 | return 0; |
418 | 0 | code = sputs(s, (const byte *)&cache_size, sizeof(cache_size), &n); |
419 | 0 | if (code < 0) |
420 | 0 | return code; |
421 | 0 | return sputs(s, (const byte *)c->values, sizeof(c->values), &n); |
422 | 0 | } |
423 | | |
424 | | int |
425 | | gx_serialize_cie_common_elements(const gs_color_space * pcs, stream * s) |
426 | 0 | { |
427 | 0 | const gs_cie_a * p = pcs->params.a; |
428 | 0 | uint n, k; |
429 | 0 | int code = gx_serialize_cspace_type(pcs, s); |
430 | |
|
431 | 0 | if (code < 0) |
432 | 0 | return code; |
433 | 0 | code = sputs(s, (const byte *)&p->common.RangeLMN, |
434 | 0 | sizeof(p->common.RangeLMN), &n); |
435 | 0 | if (code < 0) |
436 | 0 | return code; |
437 | 0 | for (k = 0; k < 3 && code >= 0; k++) |
438 | 0 | code = gx_serialize_cie_cache(&p->common.caches.DecodeLMN[k].floats, s); |
439 | 0 | if (code < 0) |
440 | 0 | return code; |
441 | 0 | code = sputs(s, (const byte *)&p->common.MatrixLMN, |
442 | 0 | sizeof(p->common.MatrixLMN), &n); |
443 | 0 | if (code < 0) |
444 | 0 | return code; |
445 | 0 | return sputs(s, (const byte *)&p->common.points, |
446 | 0 | sizeof(p->common.points), &n); |
447 | 0 | } |
448 | | |
449 | | static int |
450 | | gx_serialize_CIEA(const gs_color_space * pcs, stream * s) |
451 | 0 | { |
452 | 0 | const gs_cie_a * p = pcs->params.a; |
453 | 0 | uint n; |
454 | 0 | int code = gx_serialize_cie_common_elements(pcs, s); |
455 | |
|
456 | 0 | if (code < 0) |
457 | 0 | return code; |
458 | 0 | code = sputs(s, (const byte *)&p->RangeA, sizeof(p->RangeA), &n); |
459 | 0 | if (code < 0) |
460 | 0 | return code; |
461 | 0 | code = gx_serialize_cie_cache(&p->caches.DecodeA.floats, s); |
462 | 0 | if (code < 0) |
463 | 0 | return code; |
464 | 0 | return sputs(s, (const byte *)&p->MatrixA, sizeof(p->MatrixA), &n); |
465 | 0 | } |
466 | | |
467 | | static int |
468 | | gx_serialize_CIEABC(const gs_color_space * pcs, stream * s) |
469 | 0 | { |
470 | 0 | const gs_cie_abc * p = pcs->params.abc; |
471 | 0 | uint n, k; |
472 | 0 | int code = gx_serialize_cie_common_elements(pcs, s); |
473 | |
|
474 | 0 | if (code < 0) |
475 | 0 | return code; |
476 | 0 | code = sputs(s, (const byte *)&p->RangeABC, sizeof(p->RangeABC), &n); |
477 | 0 | if (code < 0) |
478 | 0 | return code; |
479 | 0 | code = sputs(s, (const byte *)&p->caches.skipABC, sizeof(p->caches.skipABC), &n); |
480 | 0 | if (code < 0) |
481 | 0 | return code; |
482 | 0 | if (p->caches.skipABC) |
483 | 0 | return 0; |
484 | 0 | for (k = 0; k < 3 && code >= 0; k++) |
485 | 0 | code = gx_serialize_cie_cache(&p->caches.DecodeABC.caches[k].floats, s); |
486 | 0 | if (code < 0) |
487 | 0 | return code; |
488 | 0 | return sputs(s, (const byte *)&p->MatrixABC, sizeof(p->MatrixABC), &n); |
489 | 0 | } |
490 | | |
491 | | static int |
492 | | gx_serialize_lookup_table(const gx_color_lookup_table * t, stream * s) |
493 | 0 | { |
494 | 0 | uint n; |
495 | 0 | int code = sputs(s, (const byte *)&t->n, sizeof(t->n), &n); |
496 | |
|
497 | 0 | if (code < 0) |
498 | 0 | return code; |
499 | 0 | code = sputs(s, (const byte *)&t->dims[0], sizeof(t->dims[0]) * t->n, &n); |
500 | 0 | if (code < 0) |
501 | 0 | return code; |
502 | 0 | code = sputs(s, (const byte *)&t->m, sizeof(t->m), &n); |
503 | 0 | if (code < 0) |
504 | 0 | return code; |
505 | 0 | code = sputs(s, (const byte *)&t->table->size, sizeof(t->table->size), &n); |
506 | 0 | if (code < 0) |
507 | 0 | return code; |
508 | 0 | return sputs(s, (const byte *)t->table->data, t->table->size, &n); |
509 | 0 | } |
510 | | |
511 | | static int |
512 | | gx_serialize_CIEDEF(const gs_color_space * pcs, stream * s) |
513 | 0 | { |
514 | 0 | const gs_cie_def * p = pcs->params.def; |
515 | 0 | uint n, k; |
516 | 0 | int code = gx_serialize_cie_common_elements(pcs, s); |
517 | |
|
518 | 0 | if (code < 0) |
519 | 0 | return code; |
520 | 0 | code = sputs(s, (const byte *)&p->RangeDEF, sizeof(p->RangeDEF), &n); |
521 | 0 | if (code < 0) |
522 | 0 | return code; |
523 | 0 | for (k = 0; k < 3 && code >= 0; k++) |
524 | 0 | code = gx_serialize_cie_cache(&p->caches_def.DecodeDEF[k].floats, s); |
525 | 0 | if (code < 0) |
526 | 0 | return code; |
527 | 0 | code = sputs(s, (const byte *)&p->RangeHIJ, sizeof(p->RangeHIJ), &n); |
528 | 0 | if (code < 0) |
529 | 0 | return code; |
530 | 0 | return gx_serialize_lookup_table(&p->Table, s); |
531 | 0 | } |
532 | | |
533 | | static int |
534 | | gx_serialize_CIEDEFG(const gs_color_space * pcs, stream * s) |
535 | 0 | { |
536 | 0 | const gs_cie_defg * p = pcs->params.defg; |
537 | 0 | uint n, k; |
538 | 0 | int code = gx_serialize_cie_common_elements(pcs, s); |
539 | |
|
540 | 0 | if (code < 0) |
541 | 0 | return code; |
542 | 0 | code = sputs(s, (const byte *)&p->RangeDEFG, sizeof(p->RangeDEFG), &n); |
543 | 0 | if (code < 0) |
544 | 0 | return code; |
545 | 0 | for (k = 0; k < 3 && code >= 0; k++) |
546 | 0 | code = gx_serialize_cie_cache(&p->caches_defg.DecodeDEFG[k].floats, s); |
547 | 0 | if (code < 0) |
548 | 0 | return code; |
549 | 0 | code = sputs(s, (const byte *)&p->RangeHIJK, sizeof(p->RangeHIJK), &n); |
550 | 0 | if (code < 0) |
551 | 0 | return code; |
552 | 0 | return gx_serialize_lookup_table(&p->Table, s); |
553 | 0 | } |