OSDN Git Service

binding with libharu.
[putex/putex.git] / src / texsourc / lib / libhpdf / src / hpdf_image.c
1 /*
2  * << Haru Free PDF Library >> -- hpdf_image.c
3  *
4  * URL: http://libharu.org
5  *
6  * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7  * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
8  *
9  * Permission to use, copy, modify, distribute and sell this software
10  * and its documentation for any purpose is hereby granted without fee,
11  * provided that the above copyright notice appear in all copies and
12  * that both that copyright notice and this permission notice appear
13  * in supporting documentation.
14  * It is provided "as is" without express or implied warranty.
15  *
16  */
17
18 #include "hpdf_conf.h"
19 #include "hpdf_utils.h"
20 #include "hpdf.h"
21
22 static const char *COL_CMYK = "DeviceCMYK";
23 static const char *COL_RGB = "DeviceRGB";
24 static const char *COL_GRAY = "DeviceGray";
25
26 static HPDF_STATUS
27 LoadJpegHeader (HPDF_Image   image,
28                 HPDF_Stream  stream);
29
30
31 /*---------------------------------------------------------------------------*/
32
33 static HPDF_STATUS
34 LoadJpegHeader (HPDF_Image   image,
35                 HPDF_Stream  stream)
36 {
37     HPDF_UINT16 tag;
38     HPDF_UINT16 height;
39     HPDF_UINT16 width;
40     HPDF_BYTE precision;
41     HPDF_BYTE num_components;
42     const char *color_space_name;
43     HPDF_UINT len;
44     HPDF_STATUS ret;
45     HPDF_Array array;
46
47     HPDF_PTRACE ((" HPDF_Image_LoadJpegHeader\n"));
48
49     len = 2;
50     if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&tag, &len) != HPDF_OK)
51         return HPDF_Error_GetCode (stream->error);
52
53     HPDF_UInt16Swap (&tag);
54     if (tag != 0xFFD8)
55         return HPDF_INVALID_JPEG_DATA;
56
57     /* find SOF record */
58     for (;;) {
59         HPDF_UINT16 size;
60
61         len = 2;
62         if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&tag,  &len) != HPDF_OK)
63             return HPDF_Error_GetCode (stream->error);
64
65         HPDF_UInt16Swap (&tag);
66
67         len = 2;
68         if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&size,  &len) != HPDF_OK)
69             return HPDF_Error_GetCode (stream->error);
70
71         HPDF_UInt16Swap (&size);
72
73         HPDF_PTRACE (("tag=%04X size=%u\n", tag, size));
74
75         if (tag == 0xFFC0 || tag == 0xFFC1 ||
76                 tag == 0xFFC2 || tag == 0xFFC9) {
77
78             len = 1;
79             if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&precision, &len) !=
80                     HPDF_OK)
81                 return HPDF_Error_GetCode (stream->error);
82
83             len = 2;
84             if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&height, &len) !=
85                     HPDF_OK)
86                 return HPDF_Error_GetCode (stream->error);
87
88             HPDF_UInt16Swap (&height);
89
90             len = 2;
91             if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&width, &len) != HPDF_OK)
92                 return HPDF_Error_GetCode (stream->error);
93
94              HPDF_UInt16Swap (&width);
95
96            len = 1;
97             if (HPDF_Stream_Read (stream, (HPDF_BYTE *)&num_components, &len) !=
98                     HPDF_OK)
99                 return HPDF_Error_GetCode (stream->error);
100
101             break;
102         } else if ((tag | 0x00FF) != 0xFFFF)
103             /* lost marker */
104             return HPDF_SetError (image->error, HPDF_UNSUPPORTED_JPEG_FORMAT,
105                     0);
106
107         if (HPDF_Stream_Seek (stream, size - 2, HPDF_SEEK_CUR) != HPDF_OK)
108                 return HPDF_Error_GetCode (stream->error);
109     }
110
111     if (HPDF_Dict_AddNumber (image, "Height", height) != HPDF_OK)
112         return HPDF_Error_GetCode (stream->error);
113
114     if (HPDF_Dict_AddNumber (image, "Width", width) != HPDF_OK)
115         return HPDF_Error_GetCode (stream->error);
116
117     /* classification of RGB and CMYK is less than perfect
118      * YCbCr and YCCK are classified into RGB or CMYK.
119      *
120      * It is necessary to read APP14 data to distinguish colorspace perfectly.
121
122      */
123     switch (num_components) {
124         case 1:
125             color_space_name = COL_GRAY;
126             break;
127         case 3:
128             color_space_name = COL_RGB;
129             break;
130         case 4:
131             array = HPDF_Array_New (image->mmgr);
132             if (!array)
133                 return HPDF_Error_GetCode (stream->error);
134
135             ret = HPDF_Dict_Add (image, "Decode", array);
136             if (ret != HPDF_OK)
137                 return HPDF_Error_GetCode (stream->error);
138
139             ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1));
140             ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0));
141             ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1));
142             ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0));
143             ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1));
144             ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0));
145             ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 1));
146             ret += HPDF_Array_Add (array, HPDF_Number_New (image->mmgr, 0));
147
148             if (ret != HPDF_OK)
149                 return HPDF_Error_GetCode (stream->error);
150
151             color_space_name = COL_CMYK;
152
153             break;
154         default:
155             return HPDF_SetError (image->error, HPDF_UNSUPPORTED_JPEG_FORMAT,
156                     0);
157     }
158
159     if (HPDF_Dict_Add (image, "ColorSpace",
160                 HPDF_Name_New (image->mmgr, color_space_name)) != HPDF_OK)
161         return HPDF_Error_GetCode (stream->error);
162
163     if (HPDF_Dict_Add (image, "BitsPerComponent",
164                 HPDF_Number_New (image->mmgr, precision)) != HPDF_OK)
165         return HPDF_Error_GetCode (stream->error);
166
167     return HPDF_OK;
168 }
169
170 HPDF_Image
171 HPDF_Image_LoadJpegImage  (HPDF_MMgr        mmgr,
172                            HPDF_Stream      jpeg_data,
173                            HPDF_Xref        xref)
174 {
175     HPDF_Dict image;
176     HPDF_STATUS ret = HPDF_OK;
177
178     HPDF_PTRACE ((" HPDF_Image_LoadJpegImage\n"));
179
180     image = HPDF_DictStream_New (mmgr, xref);
181     if (!image)
182         return NULL;
183
184     image->header.obj_class |= HPDF_OSUBCLASS_XOBJECT;
185
186     /* add requiered elements */
187     image->filter = HPDF_STREAM_FILTER_DCT_DECODE;
188     ret += HPDF_Dict_AddName (image, "Type", "XObject");
189     ret += HPDF_Dict_AddName (image, "Subtype", "Image");
190     if (ret != HPDF_OK)
191         return NULL;
192
193     if (LoadJpegHeader (image, jpeg_data) != HPDF_OK)
194         return NULL;
195
196     if (HPDF_Stream_Seek (jpeg_data, 0, HPDF_SEEK_SET) != HPDF_OK)
197         return NULL;
198
199     for (;;) {
200         HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ];
201         HPDF_UINT len = HPDF_STREAM_BUF_SIZ;
202         HPDF_STATUS ret = HPDF_Stream_Read (jpeg_data, buf,
203                 &len);
204
205         if (ret != HPDF_OK) {
206             if (ret == HPDF_STREAM_EOF) {
207                 if (len > 0) {
208                     ret = HPDF_Stream_Write (image->stream, buf, len);
209                     if (ret != HPDF_OK)
210                         return NULL;
211                 }
212                 break;
213             } else
214                 return NULL;
215         }
216
217         if (HPDF_Stream_Write (image->stream, buf, len) != HPDF_OK)
218             return NULL;
219     }
220
221     return image;
222 }
223
224 HPDF_Image
225 HPDF_Image_LoadJpegImageFromMem  (HPDF_MMgr    mmgr,
226                             const HPDF_BYTE   *buf,
227                                   HPDF_UINT    size,
228                                   HPDF_Xref    xref)
229 {
230         HPDF_Stream jpeg_data;
231         HPDF_Image image;
232
233         HPDF_PTRACE ((" HPDF_Image_LoadJpegImageFromMem\n"));
234
235         jpeg_data = HPDF_MemStream_New(mmgr,size);
236         if (!HPDF_Stream_Validate (jpeg_data)) {
237                 HPDF_RaiseError (mmgr->error, HPDF_INVALID_STREAM, 0);
238                 return NULL;
239         }
240
241         if (HPDF_Stream_Write (jpeg_data, buf, size) != HPDF_OK) {
242                 HPDF_Stream_Free (jpeg_data);
243                 return NULL;
244         }
245
246         image = HPDF_Image_LoadJpegImage(mmgr,jpeg_data,xref);
247
248         /* destroy file stream */
249         HPDF_Stream_Free (jpeg_data);
250
251         return image;
252 }
253
254
255 HPDF_Image
256 HPDF_Image_LoadRawImage (HPDF_MMgr          mmgr,
257                          HPDF_Stream        raw_data,
258                          HPDF_Xref          xref,
259                          HPDF_UINT          width,
260                          HPDF_UINT          height,
261                          HPDF_ColorSpace    color_space)
262 {
263     HPDF_Dict image;
264     HPDF_STATUS ret = HPDF_OK;
265     HPDF_UINT size;
266
267     HPDF_PTRACE ((" HPDF_Image_LoadRawImage\n"));
268
269     if (color_space != HPDF_CS_DEVICE_GRAY &&
270             color_space != HPDF_CS_DEVICE_RGB &&
271             color_space != HPDF_CS_DEVICE_CMYK) {
272         HPDF_SetError (mmgr->error, HPDF_INVALID_COLOR_SPACE, 0);
273         return NULL;
274     }
275
276     image = HPDF_DictStream_New (mmgr, xref);
277     if (!image)
278         return NULL;
279
280     image->header.obj_class |= HPDF_OSUBCLASS_XOBJECT;
281     ret += HPDF_Dict_AddName (image, "Type", "XObject");
282     ret += HPDF_Dict_AddName (image, "Subtype", "Image");
283     if (ret != HPDF_OK)
284         return NULL;
285
286     if (color_space == HPDF_CS_DEVICE_GRAY) {
287         size = width * height;
288         ret = HPDF_Dict_AddName (image, "ColorSpace", COL_GRAY);
289         } else if (color_space == HPDF_CS_DEVICE_CMYK) {
290                 size = width * height * 4;
291                 ret = HPDF_Dict_AddName (image, "ColorSpace", COL_CMYK);
292     } else {
293         size = width * height * 3;
294         ret = HPDF_Dict_AddName (image, "ColorSpace", COL_RGB);
295     }
296
297     if (ret != HPDF_OK)
298         return NULL;
299
300     if (HPDF_Dict_AddNumber (image, "Width", width) != HPDF_OK)
301         return NULL;
302
303     if (HPDF_Dict_AddNumber (image, "Height", height) != HPDF_OK)
304         return NULL;
305
306     if (HPDF_Dict_AddNumber (image, "BitsPerComponent", 8) != HPDF_OK)
307         return NULL;
308
309     if (HPDF_Stream_WriteToStream (raw_data, image->stream, 0, NULL) != HPDF_OK)
310         return NULL;
311
312     if (image->stream->size != size) {
313         HPDF_SetError (image->error, HPDF_INVALID_IMAGE, 0);
314         return NULL;
315     }
316
317     return image;
318 }
319
320
321 HPDF_Image
322 HPDF_Image_LoadRawImageFromMem  (HPDF_MMgr          mmgr,
323                                  const HPDF_BYTE   *buf,
324                                  HPDF_Xref          xref,
325                                  HPDF_UINT          width,
326                                  HPDF_UINT          height,
327                                  HPDF_ColorSpace    color_space,
328                                  HPDF_UINT          bits_per_component)
329 {
330     HPDF_Dict image;
331     HPDF_STATUS ret = HPDF_OK;
332     HPDF_UINT size=0;
333
334     HPDF_PTRACE ((" HPDF_Image_LoadRawImageFromMem\n"));
335
336     if (color_space != HPDF_CS_DEVICE_GRAY &&
337             color_space != HPDF_CS_DEVICE_RGB &&
338             color_space != HPDF_CS_DEVICE_CMYK) {
339         HPDF_SetError (mmgr->error, HPDF_INVALID_COLOR_SPACE, 0);
340         return NULL;
341     }
342
343     if (bits_per_component != 1 && bits_per_component != 2 &&
344             bits_per_component != 4 && bits_per_component != 8) {
345         HPDF_SetError (mmgr->error, HPDF_INVALID_IMAGE, 0);
346         return NULL;
347     }
348
349     image = HPDF_DictStream_New (mmgr, xref);
350     if (!image)
351         return NULL;
352
353     image->header.obj_class |= HPDF_OSUBCLASS_XOBJECT;
354     ret += HPDF_Dict_AddName (image, "Type", "XObject");
355     ret += HPDF_Dict_AddName (image, "Subtype", "Image");
356     if (ret != HPDF_OK)
357         return NULL;
358
359     switch (color_space) {
360         case HPDF_CS_DEVICE_GRAY:
361             size = (HPDF_UINT)((HPDF_DOUBLE)width * height / (8 / bits_per_component) + 0.876);
362             ret = HPDF_Dict_AddName (image, "ColorSpace", COL_GRAY);
363             break;
364         case HPDF_CS_DEVICE_RGB:
365             size = (HPDF_UINT)((HPDF_DOUBLE)width * height / (8 / bits_per_component) + 0.876);
366             size *= 3;
367             ret = HPDF_Dict_AddName (image, "ColorSpace", COL_RGB);
368             break;
369         case HPDF_CS_DEVICE_CMYK:
370             size = (HPDF_UINT)((HPDF_DOUBLE)width * height / (8 / bits_per_component) + 0.876);
371             size *= 4;
372             ret = HPDF_Dict_AddName (image, "ColorSpace", COL_CMYK);
373             break;
374         default:;
375     }
376
377     if (ret != HPDF_OK)
378         return NULL;
379
380     if (HPDF_Dict_AddNumber (image, "Width", width) != HPDF_OK)
381         return NULL;
382
383     if (HPDF_Dict_AddNumber (image, "Height", height) != HPDF_OK)
384         return NULL;
385
386     if (HPDF_Dict_AddNumber (image, "BitsPerComponent", bits_per_component)
387             != HPDF_OK)
388         return NULL;
389
390     if (HPDF_Stream_Write (image->stream, buf, size) != HPDF_OK)
391         return NULL;
392
393     return image;
394 }
395
396
397 HPDF_BOOL
398 HPDF_Image_Validate (HPDF_Image  image)
399 {
400     HPDF_Name subtype;
401
402     HPDF_PTRACE ((" HPDF_Image_Validate\n"));
403
404     if (!image)
405         return HPDF_FALSE;
406
407     if (image->header.obj_class != (HPDF_OSUBCLASS_XOBJECT |
408                 HPDF_OCLASS_DICT)) {
409         HPDF_RaiseError (image->error, HPDF_INVALID_IMAGE, 0);
410         return HPDF_FALSE;
411     }
412
413     subtype = HPDF_Dict_GetItem (image, "Subtype", HPDF_OCLASS_NAME);
414     if (!subtype || HPDF_StrCmp (subtype->value, "Image") != 0) {
415         HPDF_RaiseError (image->error, HPDF_INVALID_IMAGE, 0);
416         return HPDF_FALSE;
417     }
418
419     return HPDF_TRUE;
420 }
421
422
423 HPDF_EXPORT(HPDF_Point)
424 HPDF_Image_GetSize (HPDF_Image  image)
425 {
426     HPDF_Number width;
427     HPDF_Number height;
428     HPDF_Point ret = {0, 0};
429
430     HPDF_PTRACE ((" HPDF_Image_GetSize\n"));
431
432     if (!HPDF_Image_Validate (image))
433         return ret;
434
435     width = HPDF_Dict_GetItem (image, "Width", HPDF_OCLASS_NUMBER);
436     height = HPDF_Dict_GetItem (image, "Height", HPDF_OCLASS_NUMBER);
437
438     if (width && height) {
439       ret.x = (HPDF_REAL)width->value;
440       ret.y = (HPDF_REAL)height->value;
441     }
442
443     return ret;
444 }
445
446 HPDF_EXPORT(HPDF_STATUS)
447 HPDF_Image_GetSize2 (HPDF_Image  image, HPDF_Point *size)
448 {
449     HPDF_Number width;
450     HPDF_Number height;
451     size->x = 0;
452     size->y = 0;
453
454     HPDF_PTRACE ((" HPDF_Image_GetSize\n"));
455
456     if (!HPDF_Image_Validate (image))
457         return HPDF_INVALID_IMAGE;
458
459     width = HPDF_Dict_GetItem (image, "Width", HPDF_OCLASS_NUMBER);
460     height = HPDF_Dict_GetItem (image, "Height", HPDF_OCLASS_NUMBER);
461
462     if (width && height) {
463       size->x = (HPDF_REAL)width->value;
464       size->y = (HPDF_REAL)height->value;
465     }
466
467     return HPDF_OK;
468 }
469
470 HPDF_EXPORT(HPDF_UINT)
471 HPDF_Image_GetBitsPerComponent (HPDF_Image  image)
472 {
473     HPDF_Number n;
474
475     HPDF_PTRACE ((" HPDF_Image_GetBitsPerComponent\n"));
476
477     if (!HPDF_Image_Validate (image))
478         return 0;
479
480     n = HPDF_Dict_GetItem (image, "BitsPerComponent", HPDF_OCLASS_NUMBER);
481
482     if (!n)
483         return 0;
484
485     return n->value;
486 }
487
488 HPDF_EXPORT(const char*)
489 HPDF_Image_GetColorSpace (HPDF_Image  image)
490 {
491         HPDF_Name n;
492
493         HPDF_PTRACE ((" HPDF_Image_GetColorSpace\n"));
494
495         n = HPDF_Dict_GetItem (image, "ColorSpace", HPDF_OCLASS_NAME);
496
497         if (!n) {
498                 HPDF_Array a;
499
500                 HPDF_Error_Reset(image->error);
501
502                 a = HPDF_Dict_GetItem (image, "ColorSpace", HPDF_OCLASS_ARRAY);
503
504                 if (a) {
505                         n = HPDF_Array_GetItem (a, 0, HPDF_OCLASS_NAME);
506                 }
507         }
508
509         if (!n) {
510                 HPDF_CheckError (image->error);
511                 return NULL;
512         }
513
514         return n->value;
515 }
516
517 HPDF_EXPORT(HPDF_UINT)
518 HPDF_Image_GetWidth  (HPDF_Image   image)
519 {
520     return (HPDF_UINT)HPDF_Image_GetSize (image).x;
521 }
522
523 HPDF_EXPORT(HPDF_UINT)
524 HPDF_Image_GetHeight  (HPDF_Image   image)
525 {
526     return (HPDF_UINT)HPDF_Image_GetSize (image).y;
527 }
528
529 HPDF_STATUS
530 HPDF_Image_SetMask (HPDF_Image   image,
531                     HPDF_BOOL    mask)
532 {
533     HPDF_Boolean image_mask;
534
535     if (!HPDF_Image_Validate (image))
536         return HPDF_INVALID_IMAGE;
537
538     if (mask && HPDF_Image_GetBitsPerComponent (image) != 1)
539         return HPDF_SetError (image->error, HPDF_INVALID_BIT_PER_COMPONENT,
540                 0);
541
542     image_mask = HPDF_Dict_GetItem (image, "ImageMask", HPDF_OCLASS_BOOLEAN);
543     if (!image_mask) {
544         HPDF_STATUS ret;
545         image_mask = HPDF_Boolean_New (image->mmgr, HPDF_FALSE);
546
547         if ((ret = HPDF_Dict_Add (image, "ImageMask", image_mask)) != HPDF_OK)
548             return ret;
549     }
550
551     image_mask->value = mask;
552     return HPDF_OK;
553 }
554
555
556 HPDF_EXPORT(HPDF_STATUS)
557 HPDF_Image_SetMaskImage  (HPDF_Image   image,
558                           HPDF_Image   mask_image)
559 {
560     if (!HPDF_Image_Validate (image))
561         return HPDF_INVALID_IMAGE;
562
563     if (!HPDF_Image_Validate (mask_image))
564         return HPDF_INVALID_IMAGE;
565
566     if (HPDF_Image_SetMask (mask_image, HPDF_TRUE) != HPDF_OK)
567         return HPDF_CheckError (image->error);
568
569     return HPDF_Dict_Add (image, "Mask", mask_image);
570 }
571
572
573 HPDF_EXPORT(HPDF_STATUS)
574 HPDF_Image_SetColorMask (HPDF_Image   image,
575                          HPDF_UINT    rmin,
576                          HPDF_UINT    rmax,
577                          HPDF_UINT    gmin,
578                          HPDF_UINT    gmax,
579                          HPDF_UINT    bmin,
580                          HPDF_UINT    bmax)
581 {
582     HPDF_Array array;
583     const char *name;
584     HPDF_STATUS ret = HPDF_OK;
585
586     if (!HPDF_Image_Validate (image))
587         return HPDF_INVALID_IMAGE;
588
589     if (HPDF_Dict_GetItem (image, "ImageMask", HPDF_OCLASS_BOOLEAN))
590         return HPDF_RaiseError (image->error, HPDF_INVALID_OPERATION, 0);
591
592     if (HPDF_Image_GetBitsPerComponent (image) != 8)
593         return HPDF_RaiseError (image->error, HPDF_INVALID_BIT_PER_COMPONENT,
594                 0);
595
596     name = HPDF_Image_GetColorSpace (image);
597     if (!name || HPDF_StrCmp (COL_RGB, name) != 0)
598         return HPDF_RaiseError (image->error, HPDF_INVALID_COLOR_SPACE, 0);
599
600     /* Each integer must be in the range 0 to 2^BitsPerComponent - 1 */
601     if (rmax > 255 || gmax > 255 || bmax > 255)
602        return HPDF_RaiseError (image->error, HPDF_INVALID_PARAMETER, 0);
603
604     array = HPDF_Array_New (image->mmgr);
605     if (!array)
606         return HPDF_CheckError (image->error);
607
608     ret += HPDF_Dict_Add (image, "Mask", array);
609     ret += HPDF_Array_AddNumber (array, rmin);
610     ret += HPDF_Array_AddNumber (array, rmax);
611     ret += HPDF_Array_AddNumber (array, gmin);
612     ret += HPDF_Array_AddNumber (array, gmax);
613     ret += HPDF_Array_AddNumber (array, bmin);
614     ret += HPDF_Array_AddNumber (array, bmax);
615
616     if (ret != HPDF_OK)
617         return HPDF_CheckError (image->error);
618
619     return HPDF_OK;
620 }
621
622 HPDF_EXPORT(HPDF_STATUS)
623 HPDF_Image_AddSMask  (HPDF_Image  image,
624                       HPDF_Image  smask)
625 {
626
627    const char *name;
628
629    if (!HPDF_Image_Validate (image))
630        return HPDF_INVALID_IMAGE;
631    if (!HPDF_Image_Validate (smask))
632        return HPDF_INVALID_IMAGE;
633
634    if (HPDF_Dict_GetItem (image, "SMask", HPDF_OCLASS_BOOLEAN))
635        return HPDF_RaiseError (image->error, HPDF_INVALID_OPERATION, 0);
636
637    name = HPDF_Image_GetColorSpace (smask);
638    if (!name || HPDF_StrCmp (COL_GRAY, name) != 0)
639        return HPDF_RaiseError (smask->error, HPDF_INVALID_COLOR_SPACE, 0);
640
641    return HPDF_Dict_Add (image, "SMask", smask);
642 }
643
644 HPDF_STATUS
645 HPDF_Image_SetColorSpace  (HPDF_Image   image,
646                           HPDF_Array   colorspace)
647 {
648     if (!HPDF_Image_Validate (image))
649         return HPDF_INVALID_IMAGE;
650
651     return HPDF_Dict_Add (image, "ColorSpace", colorspace);
652 }
653
654
655 HPDF_STATUS
656 HPDF_Image_SetRenderingIntent  (HPDF_Image   image,
657                           const char* intent)
658 {
659     if (!HPDF_Image_Validate (image))
660         return HPDF_INVALID_IMAGE;
661
662     return HPDF_Dict_AddName (image, "Intent", intent);
663 }
664