summaryrefslogtreecommitdiff
path: root/src/cam/sdl_texture_mjpg.cpp
diff options
context:
space:
mode:
authorEric Curtin <ecurtin@redhat.com>2022-07-19 10:17:46 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-07-28 14:13:50 +0300
commitdc1f4a91dfefa9f86202ab148e05fb901b6e3e73 (patch)
tree652deb1d7018a47be60fe084c6ec0e0baf806106 /src/cam/sdl_texture_mjpg.cpp
parentc13f86704b129636bb6d84f8b8ca37826ded3238 (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.cpp70
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_);
}