1756
1763
if (bytes == NULL)
1759
if (uncompress ((Bytef *) bytes, &len,
1760
(Bytef *) src->string, src->len) != Z_OK)
1762
_csi_free (ctx, bytes);
1766
switch (src->method) {
1774
if (uncompress ((Bytef *) bytes, &len,
1775
(Bytef *) src->string, src->len) != Z_OK)
1777
_csi_free (ctx, bytes);
1785
if (lzo2a_decompress ((Bytef *) src->string, src->len,
1786
(Bytef *) bytes, &len,
1789
_csi_free (ctx, bytes);
2875
2903
int rem, len, ret, x, rowlen, instride, stride;
2876
2904
cairo_status_t status;
2878
stride = cairo_format_stride_for_width (format, width);
2879
data = malloc (stride * height);
2881
return CAIRO_STATUS_NO_MEMORY;
2883
image = cairo_image_surface_create_for_data (data, format,
2884
width, height, stride);
2885
status = cairo_surface_set_user_data (image,
2886
(const cairo_user_data_key_t *) image,
2889
cairo_surface_destroy (image);
2906
if (width == 0 || height == 0) {
2907
*image_out = cairo_image_surface_create (format, 0, 0);
2908
return CSI_STATUS_SUCCESS;
2911
if (ctx->hooks.create_source_image != NULL) {
2912
image = ctx->hooks.create_source_image (ctx->hooks.closure,
2913
format, width, height,
2916
stride = cairo_image_surface_get_stride (image);
2917
data = cairo_image_surface_get_data (image);
2919
stride = cairo_format_stride_for_width (format, width);
2920
data = malloc (stride * height);
2922
return CAIRO_STATUS_NO_MEMORY;
2924
image = cairo_image_surface_create_for_data (data, format,
2925
width, height, stride);
2926
status = cairo_surface_set_user_data (image,
2927
(const cairo_user_data_key_t *) image,
2930
cairo_surface_destroy (image);
2894
2936
switch (format) {
2915
2957
len = rowlen * height;
2920
ret = csi_file_read (src, bp, rem);
2921
if (_csi_unlikely (ret == 0)) {
2959
if (rowlen == instride &&
2960
src->type == CSI_OBJECT_TYPE_STRING &&
2961
len == src->datum.string->deflate)
2963
csi_string_t *s = src->datum.string;
2964
unsigned long out = s->deflate;
2966
switch (s->method) {
2922
2970
cairo_surface_destroy (image);
2923
2971
return _csi_error (CSI_STATUS_READ_ERROR);
2975
if (uncompress ((Bytef *) data, &out,
2976
(Bytef *) s->string, s->len) != Z_OK)
2977
goto err_decompress;
2983
if (lzo2a_decompress ((Bytef *) s->string, s->len,
2984
(Bytef *) data, &out,
2986
goto err_decompress;
2929
if (len != height * stride) {
2931
uint8_t *row = data + height * stride;
2933
/* XXX pixel conversion */
2995
status = csi_object_as_file (ctx, src, &file);
2996
if (_csi_unlikely (status)) {
2997
cairo_surface_destroy (image);
3004
ret = csi_file_read (file.datum.file, bp, rem);
3005
if (_csi_unlikely (ret == 0)) {
3006
cairo_surface_destroy (image);
3007
return _csi_error (CSI_STATUS_READ_ERROR);
3013
if (len != height * stride) {
3015
uint8_t *row = data + height * stride;
3017
/* XXX pixel conversion */
3019
case CAIRO_FORMAT_A1:
3020
for (x = rowlen; x--; ) {
3021
uint8_t byte = *--bp;
3022
row[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
3025
case CAIRO_FORMAT_A8:
3026
for (x = width; x--; )
3029
case CAIRO_FORMAT_RGB16_565:
3030
for (x = width; x--; ) {
3031
#ifdef WORDS_BIGENDIAN
3032
row[2*x + 1] = *--bp;
3033
row[2*x + 0] = *--bp;
3035
row[2*x + 0] = *--bp;
3036
row[2*x + 1] = *--bp;
3040
case CAIRO_FORMAT_RGB24:
3041
for (x = width; x--; ) {
3042
#ifdef WORDS_BIGENDIAN
3043
row[4*x + 3] = *--bp;
3044
row[4*x + 2] = *--bp;
3045
row[4*x + 1] = *--bp;
3046
row[4*x + 0] = 0xff;
3048
row[4*x + 0] = *--bp;
3049
row[4*x + 1] = *--bp;
3050
row[4*x + 2] = *--bp;
3051
row[4*x + 3] = 0xff;
3055
case CAIRO_FORMAT_RGB30:
3056
case CAIRO_FORMAT_INVALID:
3057
case CAIRO_FORMAT_ARGB32:
3058
/* stride == width */
3062
memset (row + instride, 0, stride - instride);
3065
/* need to treat last row carefully */
2934
3066
switch (format) {
2935
3067
case CAIRO_FORMAT_A1:
2936
3068
for (x = rowlen; x--; ) {
2937
3069
uint8_t byte = *--bp;
2938
row[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
3070
data[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
2941
3073
case CAIRO_FORMAT_A8:
2942
3074
for (x = width; x--; )
2945
3077
case CAIRO_FORMAT_RGB16_565:
2946
3078
for (x = width; x--; ) {
2947
3079
#ifdef WORDS_BIGENDIAN
2948
row[2*x + 1] = *--bp;
2949
row[2*x + 0] = *--bp;
3080
data[2*x + 1] = *--bp;
3081
data[2*x + 0] = *--bp;
2951
row[2*x + 0] = *--bp;
2952
row[2*x + 1] = *--bp;
3083
data[2*x + 0] = *--bp;
3084
data[2*x + 1] = *--bp;
2956
3088
case CAIRO_FORMAT_RGB24:
2957
for (x = width; x--; ) {
2958
#ifdef WORDS_BIGENDIAN
2959
row[4*x + 3] = *--bp;
2960
row[4*x + 2] = *--bp;
2961
row[4*x + 1] = *--bp;
2962
row[4*x + 0] = 0xff;
2964
row[4*x + 0] = *--bp;
2965
row[4*x + 1] = *--bp;
2966
row[4*x + 2] = *--bp;
2967
row[4*x + 3] = 0xff;
3089
for (x = width; --x>1; ) {
3090
#ifdef WORDS_BIGENDIAN
3091
data[4*x + 3] = *--bp;
3092
data[4*x + 2] = *--bp;
3093
data[4*x + 1] = *--bp;
3094
data[4*x + 0] = 0xff;
3096
data[4*x + 0] = *--bp;
3097
data[4*x + 1] = *--bp;
3098
data[4*x + 2] = *--bp;
3099
data[4*x + 3] = 0xff;
3104
/* shuffle the last couple of overlapping pixels */
3105
rgb[1][0] = data[5];
3106
rgb[1][1] = data[4];
3107
rgb[1][2] = data[3];
3108
rgb[0][0] = data[2];
3109
rgb[0][1] = data[1];
3110
rgb[0][2] = data[0];
3111
#ifdef WORDS_BIGENDIAN
3113
data[5] = rgb[1][2];
3114
data[6] = rgb[1][1];
3115
data[7] = rgb[1][0];
3117
data[1] = rgb[0][2];
3118
data[2] = rgb[0][1];
3119
data[3] = rgb[0][0];
3122
data[6] = rgb[1][2];
3123
data[5] = rgb[1][1];
3124
data[4] = rgb[1][0];
3126
data[2] = rgb[0][2];
3127
data[1] = rgb[0][1];
3128
data[0] = rgb[0][0];
3131
#ifdef WORDS_BIGENDIAN
2974
3147
/* stride == width */
2978
memset (row + instride, 0, stride - instride);
2981
/* need to treat last row carefully */
2983
case CAIRO_FORMAT_A1:
2984
for (x = rowlen; x--; ) {
2985
uint8_t byte = *--bp;
2986
data[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
2989
case CAIRO_FORMAT_A8:
2990
for (x = width; x--; )
2993
case CAIRO_FORMAT_RGB16_565:
2994
for (x = width; x--; ) {
2995
#ifdef WORDS_BIGENDIAN
2996
data[2*x + 1] = *--bp;
2997
data[2*x + 0] = *--bp;
2999
data[2*x + 0] = *--bp;
3000
data[2*x + 1] = *--bp;
3004
case CAIRO_FORMAT_RGB24:
3005
for (x = width; --x>1; ) {
3006
#ifdef WORDS_BIGENDIAN
3007
data[4*x + 3] = *--bp;
3008
data[4*x + 2] = *--bp;
3009
data[4*x + 1] = *--bp;
3010
data[4*x + 0] = 0xff;
3012
data[4*x + 0] = *--bp;
3013
data[4*x + 1] = *--bp;
3014
data[4*x + 2] = *--bp;
3015
data[4*x + 3] = 0xff;
3020
/* shuffle the last couple of overlapping pixels */
3021
rgb[1][0] = data[5];
3022
rgb[1][1] = data[4];
3023
rgb[1][2] = data[3];
3024
rgb[0][0] = data[2];
3025
rgb[0][1] = data[1];
3026
rgb[0][2] = data[0];
3027
#ifdef WORDS_BIGENDIAN
3029
data[5] = rgb[1][2];
3030
data[6] = rgb[1][1];
3031
data[7] = rgb[1][0];
3033
data[1] = rgb[0][2];
3034
data[2] = rgb[0][1];
3035
data[3] = rgb[0][0];
3038
data[6] = rgb[1][2];
3039
data[5] = rgb[1][1];
3040
data[4] = rgb[1][0];
3042
data[2] = rgb[0][2];
3043
data[1] = rgb[0][1];
3044
data[0] = rgb[0][0];
3047
#ifdef WORDS_BIGENDIAN
3060
case CAIRO_FORMAT_RGB30:
3061
case CAIRO_FORMAT_INVALID:
3062
case CAIRO_FORMAT_ARGB32:
3063
/* stride == width */
3066
memset (data + instride, 0, stride - instride);
3150
memset (data + instride, 0, stride - instride);
3068
3152
#ifndef WORDS_BIGENDIAN
3070
case CAIRO_FORMAT_A1:
3071
for (x = 0; x < len; x++) {
3072
uint8_t byte = data[x];
3073
data[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
3076
case CAIRO_FORMAT_RGB16_565:
3078
uint32_t *rgba = (uint32_t *) data;
3079
for (x = len/2; x--; rgba++) {
3080
*rgba = bswap_16 (*rgba);
3084
case CAIRO_FORMAT_ARGB32:
3086
uint32_t *rgba = (uint32_t *) data;
3087
for (x = len/4; x--; rgba++) {
3088
*rgba = bswap_32 (*rgba);
3093
case CAIRO_FORMAT_A8:
3096
case CAIRO_FORMAT_RGB30:
3097
case CAIRO_FORMAT_RGB24:
3098
case CAIRO_FORMAT_INVALID:
3154
case CAIRO_FORMAT_A1:
3155
for (x = 0; x < len; x++) {
3156
uint8_t byte = data[x];
3157
data[x] = CSI_BITSWAP8_IF_LITTLE_ENDIAN (byte);
3160
case CAIRO_FORMAT_RGB16_565:
3162
uint32_t *rgba = (uint32_t *) data;
3163
for (x = len/2; x--; rgba++) {
3164
*rgba = bswap_16 (*rgba);
3168
case CAIRO_FORMAT_ARGB32:
3170
uint32_t *rgba = (uint32_t *) data;
3171
for (x = len/4; x--; rgba++) {
3172
*rgba = bswap_32 (*rgba);
3177
case CAIRO_FORMAT_A8:
3180
case CAIRO_FORMAT_RGB30:
3181
case CAIRO_FORMAT_RGB24:
3182
case CAIRO_FORMAT_INVALID:
3188
csi_object_free (ctx, &file);
3105
3191
cairo_surface_mark_dirty (image);
3276
3362
mime_type = MIME_TYPE_PNG;
3279
status = csi_object_as_file (ctx, &obj, &file);
3280
if (_csi_unlikely (status))
3283
3366
/* XXX hook for general mime-type decoder */
3285
3368
switch (mime_type) {
3286
3369
case MIME_TYPE_NONE:
3287
status = _image_read_raw (file.datum.file,
3288
format, width, height, &image);
3370
status = _image_read_raw (ctx, &obj, format, width, height, &image);
3290
3372
case MIME_TYPE_PNG:
3373
status = csi_object_as_file (ctx, &obj, &file);
3374
if (_csi_unlikely (status))
3291
3377
status = _image_read_png (file.datum.file, &image);
3378
csi_object_free (ctx, &file);
3294
csi_object_free (ctx, &file);
3295
3381
if (_csi_unlikely (status))
5270
5356
* principally to remove the pixman ops from the profiles.
5272
5358
if (_csi_likely (_matching_images (surface, source))) {
5273
cairo_surface_flush (surface);
5274
memcpy (cairo_image_surface_get_data (surface),
5275
cairo_image_surface_get_data (source),
5276
cairo_image_surface_get_height (source) * cairo_image_surface_get_stride (source));
5277
cairo_surface_mark_dirty (surface);
5359
if (cairo_surface_get_reference_count (surface) == 1 &&
5360
cairo_surface_get_reference_count (source) == 1)
5362
_csi_peek_ostack (ctx, 0)->datum.surface = surface;
5363
_csi_peek_ostack (ctx, 1)->datum.surface = source;
5367
cairo_surface_flush (surface);
5368
memcpy (cairo_image_surface_get_data (surface),
5369
cairo_image_surface_get_data (source),
5370
cairo_image_surface_get_height (source) * cairo_image_surface_get_stride (source));
5371
cairo_surface_mark_dirty (surface);