diff options
Diffstat (limited to 'client/mjpeg_decoder.cpp')
-rw-r--r-- | client/mjpeg_decoder.cpp | 277 |
1 files changed, 0 insertions, 277 deletions
diff --git a/client/mjpeg_decoder.cpp b/client/mjpeg_decoder.cpp deleted file mode 100644 index 28d4f082..00000000 --- a/client/mjpeg_decoder.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* - Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "common.h" -#include "debug.h" -#include "utils.h" -#include "mjpeg_decoder.h" - -#if !defined(jpeg_boolean) -#define jpeg_boolean boolean -#endif - -enum { - STATE_READ_HEADER, - STATE_START_DECOMPRESS, - STATE_READ_SCANLINES, - STATE_FINISH_DECOMPRESS -}; - -extern "C" { - - static void init_source(j_decompress_ptr cinfo) - { - } - - static jpeg_boolean fill_input_buffer(j_decompress_ptr cinfo) - { - return FALSE; - } - - void mjpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes) - { - MJpegDecoder *decoder = (MJpegDecoder *)cinfo; - if (num_bytes > 0) { - if (cinfo->src->bytes_in_buffer >= (size_t)num_bytes) { - cinfo->src->next_input_byte += (size_t) num_bytes; - cinfo->src->bytes_in_buffer -= (size_t) num_bytes; - } else { - decoder->_extra_skip = num_bytes - cinfo->src->bytes_in_buffer; - cinfo->src->bytes_in_buffer = 0; - } - } - } - - static void term_source (j_decompress_ptr cinfo) - { - return; - } -} - -MJpegDecoder::MJpegDecoder(int width, int height, - int stride, - uint8_t *frame, - bool back_compat) : - _data(NULL) - , _data_size(0) - , _data_start(0) - , _data_end(0) - , _extra_skip(0) - , _width(width) - , _height(height) - , _stride(stride) - , _frame(frame) - , _back_compat(back_compat) - , _y(0) - , _state(0) -{ - memset(&_cinfo, 0, sizeof(_cinfo)); - _cinfo.err = jpeg_std_error (&_jerr); - jpeg_create_decompress (&_cinfo); - - _cinfo.src = &_jsrc; - _cinfo.src->init_source = init_source; - _cinfo.src->fill_input_buffer = fill_input_buffer; - _cinfo.src->skip_input_data = mjpeg_skip_input_data; - _cinfo.src->resync_to_restart = jpeg_resync_to_restart; - _cinfo.src->term_source = term_source; - - _scanline = new uint8_t[width * 3]; -} - -MJpegDecoder::~MJpegDecoder() -{ - jpeg_destroy_decompress(&_cinfo); - delete [] _scanline; - if (_data) { - delete [] _data; - } -} - -void MJpegDecoder::convert_scanline(void) -{ - uint32_t *row; - uint32_t c; - uint8_t *s; - unsigned x; - - ASSERT(_width % 2 == 0); - ASSERT(_height % 2 == 0); - - row = (uint32_t *)(_frame + _y * _stride); - s = _scanline; - - - if (_back_compat) { - /* We need to check for the old major and for backwards compat - a) swap r and b (done) - b) to-yuv with right values and then from-yuv with old wrong values (TODO) - */ - for (x = 0; x < _width; x++) { - c = s[2] << 16 | s[1] << 8 | s[0]; - s += 3; - *row++ = c; - } - } else { - for (x = 0; x < _width; x++) { - c = s[0] << 16 | s[1] << 8 | s[2]; - s += 3; - *row++ = c; - } - } -} - -void MJpegDecoder::append_data(uint8_t *data, size_t length) -{ - uint8_t *new_data; - size_t data_len; - - if (length == 0) { - return; - } - - if (_data_size - _data_end < length) { - /* Can't fits in tail, need to make space */ - - data_len = _data_end - _data_start; - if (_data_size - data_len < length) { - /* Can't fit at all, grow a bit */ - _data_size = _data_size + length * 2; - new_data = new uint8_t[_data_size]; - memcpy (new_data, _data + _data_start, data_len); - delete [] _data; - _data = new_data; - } else { - /* Just needs to compact */ - memmove (_data, _data + _data_start, data_len); - } - _data_start = 0; - _data_end = data_len; - } - - memcpy (_data + _data_end, data, length); - _data_end += length; -} - -bool MJpegDecoder::decode_data(uint8_t *data, size_t length) -{ - bool got_picture; - int res; - - got_picture = false; - - if (_extra_skip > 0) { - if (_extra_skip >= length) { - _extra_skip -= length; - return false; - } else { - data += _extra_skip; - length -= _extra_skip; - _extra_skip = 0; - } - } - - if (_data_end - _data_start == 0) { - /* No current data, pass in without copy */ - - _jsrc.next_input_byte = data; - _jsrc.bytes_in_buffer = length; - } else { - /* Need to combine the new and old data */ - append_data(data, length); - - _jsrc.next_input_byte = _data + _data_start; - _jsrc.bytes_in_buffer = _data_end - _data_start; - } - - switch (_state) { - case STATE_READ_HEADER: - res = jpeg_read_header(&_cinfo, TRUE); - if (res == JPEG_SUSPENDED) { - break; - } - - _cinfo.do_fancy_upsampling = FALSE; - _cinfo.do_block_smoothing = FALSE; - _cinfo.out_color_space = JCS_RGB; - - PANIC_ON(_cinfo.image_width != _width); - PANIC_ON(_cinfo.image_height != _height); - - _state = STATE_START_DECOMPRESS; - - /* fall through */ - case STATE_START_DECOMPRESS: - res = jpeg_start_decompress (&_cinfo); - - if (!res) { - break; - } - - _state = STATE_READ_SCANLINES; - - /* fall through */ - case STATE_READ_SCANLINES: - res = 0; - while (_y < _height) { - res = jpeg_read_scanlines(&_cinfo, &_scanline, 1); - - if (res == 0) { - break; - } - - convert_scanline(); - _y++; - } - if (res == 0) { - break; - } - - _state = STATE_FINISH_DECOMPRESS; - - /* fall through */ - case STATE_FINISH_DECOMPRESS: - res = jpeg_finish_decompress (&_cinfo); - - if (!res) { - break; - } - - _y = 0; - _state = STATE_READ_HEADER; - got_picture = true; - - break; - } - - if (_jsrc.next_input_byte == data) { - /* We read directly from the user, store remaining data in - buffer for next time */ - size_t read_size = _jsrc.next_input_byte - data; - - append_data(data + read_size, length - read_size); - } else { - _data_start = _jsrc.next_input_byte - _data; - _data_end = _data_start + _jsrc.bytes_in_buffer; - } - - return got_picture; -} |