image-stream.h (7178B)
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20#ifndef GUACENC_IMAGE_STREAM_H 21#define GUACENC_IMAGE_STREAM_H 22 23#include "config.h" 24#include "buffer.h" 25 26#include <cairo/cairo.h> 27 28#include <stddef.h> 29 30/** 31 * The initial number of bytes to allocate for the image data buffer. If this 32 * buffer is not sufficiently large, it will be dynamically reallocated as it 33 * grows. 34 */ 35#define GUACENC_IMAGE_STREAM_INITIAL_LENGTH 4096 36 37/** 38 * Callback function which is provided raw, encoded image data of the given 39 * length. The function is expected to return a new Cairo surface which will 40 * later (by guacenc) be freed via cairo_surface_destroy(). 41 * 42 * @param data 43 * The raw encoded image data that this function must decode. 44 * 45 * @param length 46 * The length of the image data, in bytes. 47 * 48 * @return 49 * A newly-allocated Cairo surface containing the decoded image, or NULL 50 * or decoding fails. 51 */ 52typedef cairo_surface_t* guacenc_decoder(unsigned char* data, int length); 53 54/** 55 * The current state of an allocated Guacamole image stream. 56 */ 57typedef struct guacenc_image_stream { 58 59 /** 60 * The index of the destination layer or buffer. 61 */ 62 int index; 63 64 /** 65 * The Guacamole protocol compositing operation (channel mask) to apply 66 * when drawing the image. 67 */ 68 int mask; 69 70 /** 71 * The X coordinate of the upper-left corner of the rectangle within the 72 * destination layer or buffer that the decoded image should be drawn to. 73 */ 74 int x; 75 76 /** 77 * The Y coordinate of the upper-left corner of the rectangle within the 78 * destination layer or buffer that the decoded image should be drawn to. 79 */ 80 int y; 81 82 /** 83 * Buffer of image data which will be built up over time as chunks are 84 * received via "blob" instructions. This will ultimately be passed in its 85 * entirety to the decoder function. 86 */ 87 unsigned char* buffer; 88 89 /** 90 * The number of bytes currently stored in the buffer. 91 */ 92 size_t length; 93 94 /** 95 * The maximum number of bytes that can be stored in the current buffer 96 * before it must be reallocated. 97 */ 98 size_t max_length; 99 100 /** 101 * The decoder to use when decoding the raw data received along this 102 * stream, or NULL if no such decoder exists. 103 */ 104 guacenc_decoder* decoder; 105 106} guacenc_image_stream; 107 108/** 109 * Mapping of image mimetype to corresponding decoder function. 110 */ 111typedef struct guacenc_decoder_mapping { 112 113 /** 114 * The mimetype of the image that the associated decoder can read. 115 */ 116 const char* mimetype; 117 118 /** 119 * The decoder function to use when an image stream of the associated 120 * mimetype is received. 121 */ 122 guacenc_decoder* decoder; 123 124} guacenc_decoder_mapping; 125 126/** 127 * Array of all mimetype/decoder mappings for all supported image types, 128 * terminated by an entry with a NULL mimetype. 129 */ 130extern guacenc_decoder_mapping guacenc_decoder_map[]; 131 132/** 133 * Returns the decoder associated with the given mimetype. If no such decoder 134 * exists, NULL is returned. 135 * 136 * @param mimetype 137 * The image mimetype to return the associated decoder of. 138 * 139 * @return 140 * The decoder associated with the given mimetype, or NULL if no such 141 * decoder exists. 142 */ 143guacenc_decoder* guacenc_get_decoder(const char* mimetype); 144 145/** 146 * Allocates and initializes a new image stream. This allocation is independent 147 * of the Guacamole video encoder display; the allocated guacenc_image_stream 148 * will not automatically be associated with the active display, nor will the 149 * provided layer/buffer index be validated. 150 * 151 * @param mask 152 * The Guacamole protocol compositing operation (channel mask) to apply 153 * when drawing the image. 154 * 155 * @param index 156 * The index of the layer or buffer that the image should be drawn to. 157 * 158 * @param mimetype 159 * The mimetype of the image data that will be received along this stream. 160 * 161 * @param x 162 * The X coordinate of the upper-left corner of the rectangle within the 163 * destination layer or buffer that the image should be drawn to. 164 * 165 * @param y 166 * The Y coordinate of the upper-left corner of the rectangle within the 167 * destination layer or buffer that the image should be drawn to. 168 * 169 * @return 170 * A newly-allocated and initialized guacenc_image_stream, or NULL if 171 * allocation fails. 172 */ 173guacenc_image_stream* guacenc_image_stream_alloc(int mask, int index, 174 const char* mimetype, int x, int y); 175 176/** 177 * Appends newly-received data to the internal buffer of the given image 178 * stream, such that the entire received image can be fed to the decoder as one 179 * buffer once the stream ends. 180 * 181 * @param stream 182 * The image stream that received the data. 183 * 184 * @param data 185 * The chunk of data received along the image stream. 186 * 187 * @param length 188 * The length of the chunk of data received, in bytes. 189 * 190 * @return 191 * Zero if the given data was successfully appended to the in-progress 192 * image, non-zero if an error occurs. 193 */ 194int guacenc_image_stream_receive(guacenc_image_stream* stream, 195 unsigned char* data, int length); 196 197/** 198 * Marks the end of the given image stream (no more data will be received) and 199 * invokes the associated decoder. The decoded image will be written to the 200 * given buffer as-is. If no decoder is associated with the given image stream, 201 * this function has no effect. Meta-information describing the image draw 202 * operation itself is pulled from the guacenc_image_stream, having been stored 203 * there when the image stream was created. 204 * 205 * @param stream 206 * The image stream that has ended. 207 * 208 * @param buffer 209 * The buffer that the decoded image should be written to. 210 * 211 * @return 212 * Zero if the image is written successfully, or non-zero if an error 213 * occurs. 214 */ 215int guacenc_image_stream_end(guacenc_image_stream* stream, 216 guacenc_buffer* buffer); 217 218/** 219 * Frees the given image stream and all associated data. If the image stream 220 * has not yet ended (reached end-of-stream), no image will be drawn to the 221 * associated buffer or layer. 222 * 223 * @param stream 224 * The stream to free. 225 * 226 * @return 227 * Zero if freeing the stream succeeded, or non-zero if freeing the stream 228 * failed (for example, due to an error in the free handler of the 229 * decoder). 230 */ 231int guacenc_image_stream_free(guacenc_image_stream* stream); 232 233#endif 234