tizen 2.4 release
[framework/graphics/cairo.git] / src / cairo-output-stream.c
1 /* cairo-output-stream.c: Output stream abstraction
2  *
3  * Copyright © 2005 Red Hat, Inc
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it either under the terms of the GNU Lesser General Public
7  * License version 2.1 as published by the Free Software Foundation
8  * (the "LGPL") or, at your option, under the terms of the Mozilla
9  * Public License Version 1.1 (the "MPL"). If you do not alter this
10  * notice, a recipient may use your version of this file under either
11  * the MPL or the LGPL.
12  *
13  * You should have received a copy of the LGPL along with this library
14  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16  * You should have received a copy of the MPL along with this library
17  * in the file COPYING-MPL-1.1
18  *
19  * The contents of this file are subject to the Mozilla Public License
20  * Version 1.1 (the "License"); you may not use this file except in
21  * compliance with the License. You may obtain a copy of the License at
22  * http://www.mozilla.org/MPL/
23  *
24  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26  * the specific language governing rights and limitations.
27  *
28  * The Original Code is the cairo graphics library.
29  *
30  * The Initial Developer of the Original Code is Red Hat, Inc.
31  *
32  * Author(s):
33  *      Kristian Høgsberg <krh@redhat.com>
34  */
35
36 #define _BSD_SOURCE /* for snprintf() */
37 #include "cairoint.h"
38
39 #include "cairo-output-stream-private.h"
40
41 #include "cairo-array-private.h"
42 #include "cairo-error-private.h"
43 #include "cairo-compiler-private.h"
44
45 #include <stdio.h>
46 #include <locale.h>
47 #include <errno.h>
48
49 /* Numbers printed with %f are printed with this number of significant
50  * digits after the decimal.
51  */
52 #define SIGNIFICANT_DIGITS_AFTER_DECIMAL 6
53
54 /* Numbers printed with %g are assumed to only have %CAIRO_FIXED_FRAC_BITS
55  * bits of precision available after the decimal point.
56  *
57  * FIXED_POINT_DECIMAL_DIGITS specifies the minimum number of decimal
58  * digits after the decimal point required to preserve the available
59  * precision.
60  *
61  * The conversion is:
62  *
63  * <programlisting>
64  * FIXED_POINT_DECIMAL_DIGITS = ceil( CAIRO_FIXED_FRAC_BITS * ln(2)/ln(10) )
65  * </programlisting>
66  *
67  * We can replace ceil(x) with (int)(x+1) since x will never be an
68  * integer for any likely value of %CAIRO_FIXED_FRAC_BITS.
69  */
70 #define FIXED_POINT_DECIMAL_DIGITS ((int)(CAIRO_FIXED_FRAC_BITS*0.301029996 + 1))
71
72 void
73 _cairo_output_stream_init (cairo_output_stream_t            *stream,
74                            cairo_output_stream_write_func_t  write_func,
75                            cairo_output_stream_flush_func_t  flush_func,
76                            cairo_output_stream_close_func_t  close_func)
77 {
78     stream->write_func = write_func;
79     stream->flush_func = flush_func;
80     stream->close_func = close_func;
81     stream->position = 0;
82     stream->status = CAIRO_STATUS_SUCCESS;
83     stream->closed = FALSE;
84 }
85
86 cairo_status_t
87 _cairo_output_stream_fini (cairo_output_stream_t *stream)
88 {
89     return _cairo_output_stream_close (stream);
90 }
91
92 const cairo_output_stream_t _cairo_output_stream_nil = {
93     NULL, /* write_func */
94     NULL, /* flush_func */
95     NULL, /* close_func */
96     0,    /* position */
97     CAIRO_STATUS_NO_MEMORY,
98     FALSE /* closed */
99 };
100
101 static const cairo_output_stream_t _cairo_output_stream_nil_write_error = {
102     NULL, /* write_func */
103     NULL, /* flush_func */
104     NULL, /* close_func */
105     0,    /* position */
106     CAIRO_STATUS_WRITE_ERROR,
107     FALSE /* closed */
108 };
109
110 typedef struct _cairo_output_stream_with_closure {
111     cairo_output_stream_t        base;
112     cairo_write_func_t           write_func;
113     cairo_close_func_t           close_func;
114     void                        *closure;
115 } cairo_output_stream_with_closure_t;
116
117
118 static cairo_status_t
119 closure_write (cairo_output_stream_t *stream,
120                const unsigned char *data, unsigned int length)
121 {
122     cairo_output_stream_with_closure_t *stream_with_closure =
123         (cairo_output_stream_with_closure_t *) stream;
124
125     if (stream_with_closure->write_func == NULL)
126         return CAIRO_STATUS_SUCCESS;
127
128     return stream_with_closure->write_func (stream_with_closure->closure,
129                                             data, length);
130 }
131
132 static cairo_status_t
133 closure_close (cairo_output_stream_t *stream)
134 {
135     cairo_output_stream_with_closure_t *stream_with_closure =
136         (cairo_output_stream_with_closure_t *) stream;
137
138     if (stream_with_closure->close_func != NULL)
139         return stream_with_closure->close_func (stream_with_closure->closure);
140     else
141         return CAIRO_STATUS_SUCCESS;
142 }
143
144 cairo_output_stream_t *
145 _cairo_output_stream_create (cairo_write_func_t         write_func,
146                              cairo_close_func_t         close_func,
147                              void                       *closure)
148 {
149     cairo_output_stream_with_closure_t *stream;
150
151     stream = malloc (sizeof (cairo_output_stream_with_closure_t));
152     if (unlikely (stream == NULL)) {
153         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
154         return (cairo_output_stream_t *) &_cairo_output_stream_nil;
155     }
156
157     _cairo_output_stream_init (&stream->base,
158                                closure_write, NULL, closure_close);
159     stream->write_func = write_func;
160     stream->close_func = close_func;
161     stream->closure = closure;
162
163     return &stream->base;
164 }
165
166 cairo_output_stream_t *
167 _cairo_output_stream_create_in_error (cairo_status_t status)
168 {
169     cairo_output_stream_t *stream;
170
171     /* check for the common ones */
172     if (status == CAIRO_STATUS_NO_MEMORY)
173         return (cairo_output_stream_t *) &_cairo_output_stream_nil;
174     if (status == CAIRO_STATUS_WRITE_ERROR)
175         return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
176
177     stream = malloc (sizeof (cairo_output_stream_t));
178     if (unlikely (stream == NULL)) {
179         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
180         return (cairo_output_stream_t *) &_cairo_output_stream_nil;
181     }
182
183     _cairo_output_stream_init (stream, NULL, NULL, NULL);
184     stream->status = status;
185
186     return stream;
187 }
188
189 cairo_status_t
190 _cairo_output_stream_flush (cairo_output_stream_t *stream)
191 {
192     cairo_status_t status;
193
194     if (stream->closed)
195         return stream->status;
196
197     if (stream == &_cairo_output_stream_nil ||
198         stream == &_cairo_output_stream_nil_write_error)
199     {
200         return stream->status;
201     }
202
203     if (stream->flush_func) {
204         status = stream->flush_func (stream);
205         /* Don't overwrite a pre-existing status failure. */
206         if (stream->status == CAIRO_STATUS_SUCCESS)
207             stream->status = status;
208     }
209
210     return stream->status;
211 }
212
213 cairo_status_t
214 _cairo_output_stream_close (cairo_output_stream_t *stream)
215 {
216     cairo_status_t status;
217
218     if (stream->closed)
219         return stream->status;
220
221     if (stream == &_cairo_output_stream_nil ||
222         stream == &_cairo_output_stream_nil_write_error)
223     {
224         return stream->status;
225     }
226
227     if (stream->close_func) {
228         status = stream->close_func (stream);
229         /* Don't overwrite a pre-existing status failure. */
230         if (stream->status == CAIRO_STATUS_SUCCESS)
231             stream->status = status;
232     }
233
234     stream->closed = TRUE;
235
236     return stream->status;
237 }
238
239 cairo_status_t
240 _cairo_output_stream_destroy (cairo_output_stream_t *stream)
241 {
242     cairo_status_t status;
243
244     assert (stream != NULL);
245
246     if (stream == &_cairo_output_stream_nil ||
247         stream == &_cairo_output_stream_nil_write_error)
248     {
249         return stream->status;
250     }
251
252     status = _cairo_output_stream_fini (stream);
253     free (stream);
254
255     return status;
256 }
257
258 void
259 _cairo_output_stream_write (cairo_output_stream_t *stream,
260                             const void *data, size_t length)
261 {
262     if (length == 0)
263         return;
264
265     if (stream->status)
266         return;
267
268     stream->status = stream->write_func (stream, data, length);
269     stream->position += length;
270 }
271
272 void
273 _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
274                                        const unsigned char *data,
275                                        size_t length)
276 {
277     const char hex_chars[] = "0123456789abcdef";
278     char buffer[2];
279     unsigned int i, column;
280
281     if (stream->status)
282         return;
283
284     for (i = 0, column = 0; i < length; i++, column++) {
285         if (column == 38) {
286             _cairo_output_stream_write (stream, "\n", 1);
287             column = 0;
288         }
289         buffer[0] = hex_chars[(data[i] >> 4) & 0x0f];
290         buffer[1] = hex_chars[data[i] & 0x0f];
291         _cairo_output_stream_write (stream, buffer, 2);
292     }
293 }
294
295 /* Format a double in a locale independent way and trim trailing
296  * zeros.  Based on code from Alex Larson <alexl@redhat.com>.
297  * http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
298  *
299  * The code in the patch is copyright Red Hat, Inc under the LGPL, but
300  * has been relicensed under the LGPL/MPL dual license for inclusion
301  * into cairo (see COPYING). -- Kristian Høgsberg <krh@redhat.com>
302  */
303 static void
304 _cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precision)
305 {
306     struct lconv *locale_data;
307     const char *decimal_point;
308     int decimal_point_len;
309     char *p;
310     int decimal_len;
311     int num_zeros, decimal_digits;
312
313     /* Omit the minus sign from negative zero. */
314     if (d == 0.0)
315         d = 0.0;
316
317     locale_data = localeconv ();
318     decimal_point = locale_data->decimal_point;
319     decimal_point_len = strlen (decimal_point);
320
321     assert (decimal_point_len != 0);
322
323     if (limited_precision) {
324         snprintf (buffer, size, "%.*f", FIXED_POINT_DECIMAL_DIGITS, d);
325     } else {
326         /* Using "%f" to print numbers less than 0.1 will result in
327          * reduced precision due to the default 6 digits after the
328          * decimal point.
329          *
330          * For numbers is < 0.1, we print with maximum precision and count
331          * the number of zeros between the decimal point and the first
332          * significant digit. We then print the number again with the
333          * number of decimal places that gives us the required number of
334          * significant digits. This ensures the number is correctly
335          * rounded.
336          */
337         if (fabs (d) >= 0.1) {
338             snprintf (buffer, size, "%f", d);
339         } else {
340             snprintf (buffer, size, "%.18f", d);
341             p = buffer;
342
343             if (*p == '+' || *p == '-')
344                 p++;
345
346             while (_cairo_isdigit (*p))
347                 p++;
348
349             if (strncmp (p, decimal_point, decimal_point_len) == 0)
350                 p += decimal_point_len;
351
352             num_zeros = 0;
353             while (*p++ == '0')
354                 num_zeros++;
355
356             decimal_digits = num_zeros + SIGNIFICANT_DIGITS_AFTER_DECIMAL;
357
358             if (decimal_digits < 18)
359                 snprintf (buffer, size, "%.*f", decimal_digits, d);
360         }
361     }
362     p = buffer;
363
364     if (*p == '+' || *p == '-')
365         p++;
366
367     while (_cairo_isdigit (*p))
368         p++;
369
370     if (strncmp (p, decimal_point, decimal_point_len) == 0) {
371         *p = '.';
372         decimal_len = strlen (p + decimal_point_len);
373         memmove (p + 1, p + decimal_point_len, decimal_len);
374         p[1 + decimal_len] = 0;
375
376         /* Remove trailing zeros and decimal point if possible. */
377         for (p = p + decimal_len; *p == '0'; p--)
378             *p = 0;
379
380         if (*p == '.') {
381             *p = 0;
382             p--;
383         }
384     }
385 }
386
387 enum {
388     LENGTH_MODIFIER_LONG = 0x100
389 };
390
391 /* Here's a limited reimplementation of printf.  The reason for doing
392  * this is primarily to special case handling of doubles.  We want
393  * locale independent formatting of doubles and we want to trim
394  * trailing zeros.  This is handled by dtostr() above, and the code
395  * below handles everything else by calling snprintf() to do the
396  * formatting.  This functionality is only for internal use and we
397  * only implement the formats we actually use.
398  */
399 void
400 _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
401                               const char *fmt, va_list ap)
402 {
403 #define SINGLE_FMT_BUFFER_SIZE 32
404     char buffer[512], single_fmt[SINGLE_FMT_BUFFER_SIZE];
405     int single_fmt_length;
406     char *p;
407     const char *f, *start;
408     int length_modifier, width;
409     cairo_bool_t var_width;
410
411     if (stream->status)
412         return;
413
414     f = fmt;
415     p = buffer;
416     while (*f != '\0') {
417         if (p == buffer + sizeof (buffer)) {
418             _cairo_output_stream_write (stream, buffer, sizeof (buffer));
419             p = buffer;
420         }
421
422         if (*f != '%') {
423             *p++ = *f++;
424             continue;
425         }
426
427         start = f;
428         f++;
429
430         if (*f == '0')
431             f++;
432
433         var_width = FALSE;
434         if (*f == '*') {
435             var_width = TRUE;
436             f++;
437         }
438
439         while (_cairo_isdigit (*f))
440             f++;
441
442         length_modifier = 0;
443         if (*f == 'l') {
444             length_modifier = LENGTH_MODIFIER_LONG;
445             f++;
446         }
447
448         /* The only format strings exist in the cairo implementation
449          * itself. So there's an internal consistency problem if any
450          * of them is larger than our format buffer size. */
451         single_fmt_length = f - start + 1;
452         assert (single_fmt_length + 1 <= SINGLE_FMT_BUFFER_SIZE);
453
454         /* Reuse the format string for this conversion. */
455         memcpy (single_fmt, start, single_fmt_length);
456         single_fmt[single_fmt_length] = '\0';
457
458         /* Flush contents of buffer before snprintf()'ing into it. */
459         _cairo_output_stream_write (stream, buffer, p - buffer);
460
461         /* We group signed and unsigned together in this switch, the
462          * only thing that matters here is the size of the arguments,
463          * since we're just passing the data through to sprintf(). */
464         switch (*f | length_modifier) {
465         case '%':
466             buffer[0] = *f;
467             buffer[1] = 0;
468             break;
469         case 'd':
470         case 'u':
471         case 'o':
472         case 'x':
473         case 'X':
474             if (var_width) {
475                 width = va_arg (ap, int);
476                 snprintf (buffer, sizeof buffer,
477                           single_fmt, width, va_arg (ap, int));
478             } else {
479                 snprintf (buffer, sizeof buffer, single_fmt, va_arg (ap, int));
480             }
481             break;
482         case 'd' | LENGTH_MODIFIER_LONG:
483         case 'u' | LENGTH_MODIFIER_LONG:
484         case 'o' | LENGTH_MODIFIER_LONG:
485         case 'x' | LENGTH_MODIFIER_LONG:
486         case 'X' | LENGTH_MODIFIER_LONG:
487             if (var_width) {
488                 width = va_arg (ap, int);
489                 snprintf (buffer, sizeof buffer,
490                           single_fmt, width, va_arg (ap, long int));
491             } else {
492                 snprintf (buffer, sizeof buffer,
493                           single_fmt, va_arg (ap, long int));
494             }
495             break;
496         case 's':
497             snprintf (buffer, sizeof buffer,
498                       single_fmt, va_arg (ap, const char *));
499             break;
500         case 'f':
501             _cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double), FALSE);
502             break;
503         case 'g':
504             _cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double), TRUE);
505             break;
506         case 'c':
507             buffer[0] = va_arg (ap, int);
508             buffer[1] = 0;
509             break;
510         default:
511             ASSERT_NOT_REACHED;
512         }
513         p = buffer + strlen (buffer);
514         f++;
515     }
516
517     _cairo_output_stream_write (stream, buffer, p - buffer);
518 }
519
520 void
521 _cairo_output_stream_printf (cairo_output_stream_t *stream,
522                              const char *fmt, ...)
523 {
524     va_list ap;
525
526     va_start (ap, fmt);
527
528     _cairo_output_stream_vprintf (stream, fmt, ap);
529
530     va_end (ap);
531 }
532
533 long
534 _cairo_output_stream_get_position (cairo_output_stream_t *stream)
535 {
536     return stream->position;
537 }
538
539 cairo_status_t
540 _cairo_output_stream_get_status (cairo_output_stream_t *stream)
541 {
542     return stream->status;
543 }
544
545 /* Maybe this should be a configure time option, so embedded targets
546  * don't have to pull in stdio. */
547
548
549 typedef struct _stdio_stream {
550     cairo_output_stream_t        base;
551     FILE                        *file;
552 } stdio_stream_t;
553
554 static cairo_status_t
555 stdio_write (cairo_output_stream_t *base,
556              const unsigned char *data, unsigned int length)
557 {
558     stdio_stream_t *stream = (stdio_stream_t *) base;
559
560     if (fwrite (data, 1, length, stream->file) != length)
561         return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
562
563     return CAIRO_STATUS_SUCCESS;
564 }
565
566 static cairo_status_t
567 stdio_flush (cairo_output_stream_t *base)
568 {
569     stdio_stream_t *stream = (stdio_stream_t *) base;
570
571     fflush (stream->file);
572
573     if (ferror (stream->file))
574         return _cairo_error (CAIRO_STATUS_WRITE_ERROR);
575     else
576         return CAIRO_STATUS_SUCCESS;
577 }
578
579 static cairo_status_t
580 stdio_close (cairo_output_stream_t *base)
581 {
582     cairo_status_t status;
583     stdio_stream_t *stream = (stdio_stream_t *) base;
584
585     status = stdio_flush (base);
586
587     fclose (stream->file);
588
589     return status;
590 }
591
592 cairo_output_stream_t *
593 _cairo_output_stream_create_for_file (FILE *file)
594 {
595     stdio_stream_t *stream;
596
597     if (file == NULL) {
598         _cairo_error_throw (CAIRO_STATUS_WRITE_ERROR);
599         return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
600     }
601
602     stream = malloc (sizeof *stream);
603     if (unlikely (stream == NULL)) {
604         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
605         return (cairo_output_stream_t *) &_cairo_output_stream_nil;
606     }
607
608     _cairo_output_stream_init (&stream->base,
609                                stdio_write, stdio_flush, stdio_flush);
610     stream->file = file;
611
612     return &stream->base;
613 }
614
615 cairo_output_stream_t *
616 _cairo_output_stream_create_for_filename (const char *filename)
617 {
618     stdio_stream_t *stream;
619     FILE *file;
620
621     if (filename == NULL)
622         return _cairo_null_stream_create ();
623
624     file = fopen (filename, "wb");
625     if (file == NULL) {
626         switch (errno) {
627         case ENOMEM:
628             _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
629             return (cairo_output_stream_t *) &_cairo_output_stream_nil;
630         default:
631             _cairo_error_throw (CAIRO_STATUS_WRITE_ERROR);
632             return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
633         }
634     }
635
636     stream = malloc (sizeof *stream);
637     if (unlikely (stream == NULL)) {
638         fclose (file);
639         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
640         return (cairo_output_stream_t *) &_cairo_output_stream_nil;
641     }
642
643     _cairo_output_stream_init (&stream->base,
644                                stdio_write, stdio_flush, stdio_close);
645     stream->file = file;
646
647     return &stream->base;
648 }
649
650
651 typedef struct _memory_stream {
652     cairo_output_stream_t       base;
653     cairo_array_t               array;
654 } memory_stream_t;
655
656 static cairo_status_t
657 memory_write (cairo_output_stream_t *base,
658               const unsigned char *data, unsigned int length)
659 {
660     memory_stream_t *stream = (memory_stream_t *) base;
661
662     return _cairo_array_append_multiple (&stream->array, data, length);
663 }
664
665 static cairo_status_t
666 memory_close (cairo_output_stream_t *base)
667 {
668     memory_stream_t *stream = (memory_stream_t *) base;
669
670     _cairo_array_fini (&stream->array);
671
672     return CAIRO_STATUS_SUCCESS;
673 }
674
675 cairo_output_stream_t *
676 _cairo_memory_stream_create (void)
677 {
678     memory_stream_t *stream;
679
680     stream = malloc (sizeof *stream);
681     if (unlikely (stream == NULL)) {
682         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
683         return (cairo_output_stream_t *) &_cairo_output_stream_nil;
684     }
685
686     _cairo_output_stream_init (&stream->base, memory_write, NULL, memory_close);
687     _cairo_array_init (&stream->array, 1);
688
689     return &stream->base;
690 }
691
692 cairo_status_t
693 _cairo_memory_stream_destroy (cairo_output_stream_t *abstract_stream,
694                               unsigned char **data_out,
695                               unsigned long *length_out)
696 {
697     memory_stream_t *stream;
698     cairo_status_t status;
699     void *data;
700
701     status = abstract_stream->status;
702     if (unlikely (status))
703         return _cairo_output_stream_destroy (abstract_stream);
704
705     stream = (memory_stream_t *) abstract_stream;
706
707     *length_out = _cairo_array_num_elements (&stream->array);
708     *data_out = malloc (*length_out);
709     if (unlikely (*data_out == NULL)) {
710         status = _cairo_output_stream_destroy (abstract_stream);
711         assert (status == CAIRO_STATUS_SUCCESS);
712         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
713     }
714
715     data = _cairo_array_index (&stream->array, 0);
716     if (data == NULL) {
717         free (*data_out);
718         return _cairo_error (CAIRO_STATUS_NULL_POINTER);
719     }
720
721     memcpy (*data_out, data, *length_out);
722
723     return _cairo_output_stream_destroy (abstract_stream);
724 }
725
726 void
727 _cairo_memory_stream_copy (cairo_output_stream_t *base,
728                            cairo_output_stream_t *dest)
729 {
730     memory_stream_t *stream = (memory_stream_t *) base;
731
732     if (dest->status)
733         return;
734
735     if (base->status) {
736         dest->status = base->status;
737         return;
738     }
739
740     _cairo_output_stream_write (dest,
741                                 _cairo_array_index (&stream->array, 0),
742                                 _cairo_array_num_elements (&stream->array));
743 }
744
745 int
746 _cairo_memory_stream_length (cairo_output_stream_t *base)
747 {
748     memory_stream_t *stream = (memory_stream_t *) base;
749
750     return _cairo_array_num_elements (&stream->array);
751 }
752
753 static cairo_status_t
754 null_write (cairo_output_stream_t *base,
755             const unsigned char *data, unsigned int length)
756 {
757     return CAIRO_STATUS_SUCCESS;
758 }
759
760 cairo_output_stream_t *
761 _cairo_null_stream_create (void)
762 {
763     cairo_output_stream_t *stream;
764
765     stream = malloc (sizeof *stream);
766     if (unlikely (stream == NULL)) {
767         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
768         return (cairo_output_stream_t *) &_cairo_output_stream_nil;
769     }
770
771     _cairo_output_stream_init (stream, null_write, NULL, NULL);
772
773     return stream;
774 }