diff options
author | Eric Curtin <ecurtin@redhat.com> | 2022-07-19 10:17:46 +0100 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2022-07-28 14:13:50 +0300 |
commit | dc1f4a91dfefa9f86202ab148e05fb901b6e3e73 (patch) | |
tree | 652deb1d7018a47be60fe084c6ec0e0baf806106 /src/cam/sdl_texture_mjpg.cpp | |
parent | c13f86704b129636bb6d84f8b8ca37826ded3238 (diff) |
cam: sdl_sink: Use libjpeg over SDL2_image
We were using the libjpeg functionality of SDL2_image only, instead just
use libjpeg directly to reduce our dependancy count, it is a more
commonly available library.
Signed-off-by: Eric Curtin <ecurtin@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Diffstat (limited to 'src/cam/sdl_texture_mjpg.cpp')
-rw-r--r-- | src/cam/sdl_texture_mjpg.cpp | 70 |
1 files changed, 64 insertions, 6 deletions
diff --git a/src/cam/sdl_texture_mjpg.cpp b/src/cam/sdl_texture_mjpg.cpp index 69e99ad3..7eddc00c 100644 --- a/src/cam/sdl_texture_mjpg.cpp +++ b/src/cam/sdl_texture_mjpg.cpp @@ -7,19 +7,77 @@ #include "sdl_texture_mjpg.h" -#include <SDL2/SDL_image.h> +#include <iostream> +#include <setjmp.h> +#include <stdio.h> + +#include <jpeglib.h> using namespace libcamera; +struct JpegErrorManager : public jpeg_error_mgr { + JpegErrorManager() + { + jpeg_std_error(this); + error_exit = errorExit; + output_message = outputMessage; + } + + static void errorExit(j_common_ptr cinfo) + { + JpegErrorManager *self = + static_cast<JpegErrorManager *>(cinfo->err); + longjmp(self->escape_, 1); + } + + static void outputMessage([[maybe_unused]] j_common_ptr cinfo) + { + } + + jmp_buf escape_; +}; + SDLTextureMJPG::SDLTextureMJPG(const SDL_Rect &rect) - : SDLTexture(rect, SDL_PIXELFORMAT_RGB24, 0) + : SDLTexture(rect, SDL_PIXELFORMAT_RGB24, rect.w * 3), + rgb_(std::make_unique<unsigned char[]>(pitch_ * rect.h)) { } +int SDLTextureMJPG::decompress(const Span<uint8_t> &data) +{ + struct jpeg_decompress_struct cinfo; + + JpegErrorManager errorManager; + if (setjmp(errorManager.escape_)) { + /* libjpeg found an error */ + jpeg_destroy_decompress(&cinfo); + std::cerr << "JPEG decompression error" << std::endl; + return -EINVAL; + } + + cinfo.err = &errorManager; + jpeg_create_decompress(&cinfo); + + jpeg_mem_src(&cinfo, data.data(), data.size()); + + jpeg_read_header(&cinfo, TRUE); + + jpeg_start_decompress(&cinfo); + + for (int i = 0; cinfo.output_scanline < cinfo.output_height; ++i) { + JSAMPROW rowptr = rgb_.get() + i * pitch_; + jpeg_read_scanlines(&cinfo, &rowptr, 1); + } + + jpeg_finish_decompress(&cinfo); + + jpeg_destroy_decompress(&cinfo); + + return 0; +} + void SDLTextureMJPG::update(const Span<uint8_t> &data) { - SDL_RWops *bufferStream = SDL_RWFromMem(data.data(), data.size()); - SDL_Surface *frame = IMG_Load_RW(bufferStream, 0); - SDL_UpdateTexture(ptr_, nullptr, frame->pixels, frame->pitch); - SDL_FreeSurface(frame); + decompress(data); + SDL_UpdateTexture(ptr_, nullptr, rgb_.get(), pitch_); } |