/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* Copyright (C) 2009-2015 Red Hat, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see . */ #ifndef IMAGE_ENCODERS_H_ #define IMAGE_ENCODERS_H_ #include #include #include #include #include #include "stat.h" #include "red-parse-qxl.h" #include "glz-encoder.h" #include "jpeg-encoder.h" #ifdef USE_LZ4 #include "lz4-encoder.h" #endif #include "zlib-encoder.h" SPICE_BEGIN_DECLS struct RedClient; typedef struct RedCompressBuf RedCompressBuf; typedef struct ImageEncoders ImageEncoders; typedef struct ImageEncoderSharedData ImageEncoderSharedData; typedef struct GlzSharedDictionary GlzSharedDictionary; typedef struct GlzImageRetention GlzImageRetention; void image_encoder_shared_init(ImageEncoderSharedData *shared_data); void image_encoder_shared_stat_reset(ImageEncoderSharedData *shared_data); void image_encoder_shared_stat_print(const ImageEncoderSharedData *shared_data); void image_encoders_init(ImageEncoders *enc, ImageEncoderSharedData *shared_data); void image_encoders_free(ImageEncoders *enc); int image_encoders_free_some_independent_glz_drawables(ImageEncoders *enc); void image_encoders_free_glz_drawables(ImageEncoders *enc); void image_encoders_free_glz_drawables_to_free(ImageEncoders* enc); gboolean image_encoders_glz_create(ImageEncoders *enc, uint8_t id); void image_encoders_glz_get_restore_data(ImageEncoders *enc, uint8_t *out_id, GlzEncDictRestoreData *out_data); gboolean image_encoders_glz_encode_lock(ImageEncoders *enc); void image_encoders_glz_encode_unlock(ImageEncoders *enc); void glz_retention_free_drawables(GlzImageRetention *ret); void glz_retention_detach_drawables(GlzImageRetention *ret); #define RED_COMPRESS_BUF_SIZE (1024 * 64) struct RedCompressBuf { RedCompressBuf *send_next; /* This buffer provide space for compression algorithms. * Some algorithms access the buffer as an array of 32 bit words * so is defined to make sure is always aligned that way. */ union { uint8_t bytes[RED_COMPRESS_BUF_SIZE]; uint32_t words[RED_COMPRESS_BUF_SIZE / 4]; } buf; }; static inline void compress_buf_free(RedCompressBuf *buf) { g_free(buf); } gboolean image_encoders_get_glz_dictionary(ImageEncoders *enc, struct RedClient *client, uint8_t id, int window_size); gboolean image_encoders_restore_glz_dictionary(ImageEncoders *enc, struct RedClient *client, uint8_t id, GlzEncDictRestoreData *restore_data); typedef struct { RedCompressBuf *bufs_head; RedCompressBuf *bufs_tail; jmp_buf jmp_env; union { struct { SpiceChunks *chunks; int next; int stride; int reverse; } lines_data; struct { RedCompressBuf* next; int size_left; } compressed_data; // for encoding data that was already compressed by another method } u; } EncoderData; typedef struct { QuicUsrContext usr; EncoderData data; } QuicData; typedef struct { LzUsrContext usr; EncoderData data; } LzData; typedef struct { JpegEncoderUsrContext usr; EncoderData data; } JpegData; #ifdef USE_LZ4 typedef struct { Lz4EncoderUsrContext usr; EncoderData data; } Lz4Data; #endif typedef struct { ZlibEncoderUsrContext usr; EncoderData data; } ZlibData; typedef struct { GlzEncoderUsrContext usr; EncoderData data; } GlzData; struct GlzImageRetention { Ring ring; }; static inline void glz_retention_init(GlzImageRetention *ret) { ring_init(&ret->ring); } struct ImageEncoderSharedData { uint32_t glz_drawable_count; stat_info_t off_stat; stat_info_t lz_stat; stat_info_t glz_stat; stat_info_t quic_stat; stat_info_t jpeg_stat; stat_info_t zlib_glz_stat; stat_info_t jpeg_alpha_stat; stat_info_t lz4_stat; }; struct ImageEncoders { ImageEncoderSharedData *shared_data; QuicData quic_data; QuicContext *quic; LzData lz_data; LzContext *lz; int jpeg_quality; JpegData jpeg_data; JpegEncoderContext *jpeg; #ifdef USE_LZ4 Lz4Data lz4_data; Lz4EncoderContext *lz4; #endif int zlib_level; ZlibData zlib_data; ZlibEncoder *zlib; /* global lz encoding entities */ GlzSharedDictionary *glz_dict; GlzEncoderContext *glz; GlzData glz_data; Ring glz_drawables; // all the living lz drawable, ordered by encoding time Ring glz_drawables_inst_to_free; // list of instances to be freed pthread_mutex_t glz_drawables_inst_to_free_lock; }; typedef struct compress_send_data_t { RedCompressBuf *comp_buf; uint32_t comp_buf_size; SpicePalette *lzplt_palette; gboolean is_lossy; } compress_send_data_t; bool image_encoders_compress_quic(ImageEncoders *enc, SpiceImage *dest, SpiceBitmap *src, compress_send_data_t* o_comp_data); bool image_encoders_compress_lz(ImageEncoders *enc, SpiceImage *dest, SpiceBitmap *src, compress_send_data_t* o_comp_data); bool image_encoders_compress_jpeg(ImageEncoders *enc, SpiceImage *dest, SpiceBitmap *src, compress_send_data_t* o_comp_data); #ifdef USE_LZ4 bool image_encoders_compress_lz4(ImageEncoders *enc, SpiceImage *dest, SpiceBitmap *src, compress_send_data_t* o_comp_data); #endif bool image_encoders_compress_glz(ImageEncoders *enc, SpiceImage *dest, SpiceBitmap *src, RedDrawable *red_drawable, GlzImageRetention *glz_retention, compress_send_data_t* o_comp_data, gboolean enable_zlib_glz_wrap); #define RED_RELEASE_BUNCH_SIZE 64 SPICE_END_DECLS #endif /* IMAGE_ENCODERS_H_ */