summaryrefslogtreecommitdiff
path: root/src/codec/stb_image
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2023-11-06 11:54:08 -0500
committerAndrew Opalach <andrew@akon.city> 2023-11-06 11:54:08 -0500
commita48a68cfb04b2020737c0adfb0e7667451a22b5c (patch)
treea92121897f84298c3798a4f2ba56de45cd100eab /src/codec/stb_image
downloadcamu-a48a68cfb04b2020737c0adfb0e7667451a22b5c.tar.gz
camu-a48a68cfb04b2020737c0adfb0e7667451a22b5c.tar.bz2
camu-a48a68cfb04b2020737c0adfb0e7667451a22b5c.zip
Add camu
- Subprojects temporarily omitted Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/codec/stb_image')
-rw-r--r--src/codec/stb_image/decoder.h11
-rw-r--r--src/codec/stb_image/demuxer.h12
-rw-r--r--src/codec/stb_image/impl.c155
3 files changed, 178 insertions, 0 deletions
diff --git a/src/codec/stb_image/decoder.h b/src/codec/stb_image/decoder.h
new file mode 100644
index 0000000..7083a09
--- /dev/null
+++ b/src/codec/stb_image/decoder.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "../codec.h"
+
+struct camu_stbi_decoder {
+ struct camu_decoder dec;
+ void (*callback)(void *, struct camu_frame *);
+ void (*userdata);
+};
+
+struct camu_decoder *camu_stbi_decoder_create(void);
diff --git a/src/codec/stb_image/demuxer.h b/src/codec/stb_image/demuxer.h
new file mode 100644
index 0000000..52f9256
--- /dev/null
+++ b/src/codec/stb_image/demuxer.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "../codec.h"
+
+struct camu_stbi_demuxer {
+ struct camu_demuxer demux;
+ struct cch_handle *handle;
+ struct aki_buffer buffer;
+ bool eof;
+};
+
+struct camu_demuxer *camu_stbi_demuxer_create(void);
diff --git a/src/codec/stb_image/impl.c b/src/codec/stb_image/impl.c
new file mode 100644
index 0000000..953cca8
--- /dev/null
+++ b/src/codec/stb_image/impl.c
@@ -0,0 +1,155 @@
+#include <al/lib.h>
+#include <aki/common.h>
+#include "../common.h"
+#define STB_IMAGE_IMPLEMENTATION
+#define STBI_NO_STDIO
+#define STBI_NO_FAILURE_STRINGS
+#define STB_IMAGE_STATIC
+#define STBI_MALLOC camu_page_alloc
+#define STBI_FREE al_free
+#define STBI_REALLOC al_realloc
+#include <stb_image.h>
+
+#include "../../cache/entry.h"
+
+#include "demuxer.h"
+#include "decoder.h"
+
+static bool stbi_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handle)
+{
+ struct camu_stbi_demuxer *stb = (struct camu_stbi_demuxer *)demux;
+
+ stb->handle = handle;
+ aki_buffer_init(&stb->buffer);
+ stb->eof = false;
+
+ cch_handle_seek(stb->handle, 0, SEEK_SET);
+ off_t size = cch_entry_get_size(stb->handle->entry);
+ aki_buffer_ensure_space(&stb->buffer, size);
+ cch_handle_read(stb->handle, aki_buffer_get_ptr(&stb->buffer, 0), size);
+ stb->buffer.size = size;
+ s32 w, h, channels;
+ stbi_info_from_memory(aki_buffer_get_ptr(&stb->buffer, 0), stb->buffer.size, &w, &h, &channels);
+
+ struct camu_stream stream = { 0 };
+ stream.type = CAMU_NORMAL;
+ stream.video.width = w;
+ stream.video.height = h;
+
+ al_array_push(stb->demux.streams, stream);
+
+ return true;
+}
+
+static s32 stbi_demuxer_get_packet(struct camu_demuxer *demux, struct camu_packet *packet)
+{
+ struct camu_stbi_demuxer *stb = (struct camu_stbi_demuxer *)demux;
+ if (stb->eof) return CAMU_ERR_EOF;
+ packet->type = CAMU_NORMAL;
+ packet->buffer = &stb->buffer;
+ stb->eof = true;
+ return CAMU_OK;
+}
+
+static s64 stbi_demuxer_get_duration(struct camu_demuxer *demux)
+{
+ (void)demux;
+ return 0;
+}
+
+static bool stbi_demuxer_seek(struct camu_demuxer *demux, s64 pos)
+{
+ (void)demux;
+ (void)pos;
+ return true;
+}
+
+static void stbi_demuxer_free(struct camu_demuxer **demux)
+{
+ struct camu_stbi_demuxer *stb = (struct camu_stbi_demuxer *)*demux;
+ al_free(stb);
+ *demux = NULL;
+}
+
+static bool stbi_decoder_init(struct camu_decoder *dec, struct camu_renderer *renderer, struct camu_stream *stream)
+{
+ struct camu_stbi_decoder *stb = (struct camu_stbi_decoder *)dec;
+ (void)stb;
+ (void)stream;
+ (void)renderer;
+ return true;
+}
+
+static void stbi_decoder_set_callback(struct camu_decoder *dec, void (*callback)(void *, struct camu_frame *), void *userdata)
+{
+ struct camu_stbi_decoder *stb = (struct camu_stbi_decoder *)dec;
+ stb->callback = callback;
+ stb->userdata = userdata;
+}
+
+static s32 stbi_decoder_push(struct camu_decoder *dec, struct camu_packet *packet)
+{
+ if (!packet) return CAMU_OK;
+
+ struct camu_stbi_decoder *stb = (struct camu_stbi_decoder *)dec;
+
+ s32 w, h, channels;
+ u8 *pixels = stbi_load_from_memory(aki_buffer_get_ptr(packet->buffer, 0),
+ packet->buffer->size, &w, &h, &channels, 4);
+
+ struct camu_frame *frame = al_alloc_object(struct camu_frame);
+ frame->type = CAMU_NORMAL;
+ frame->data = pixels;
+ frame->width = stb->dec.stream->video.width;
+ frame->height = stb->dec.stream->video.height;
+ frame->fmt = CAMU_PIXEL_FMT_RGBA;
+ frame->pts = 0.0;
+ frame->flags = 0;
+
+ stb->callback(stb->userdata, frame);
+
+ return CAMU_OK;
+}
+
+static void stbi_decoder_flush(struct camu_decoder *dec)
+{
+ (void)dec;
+}
+
+static s32 stbi_decoder_process(struct camu_decoder *dec)
+{
+ (void)dec;
+ return CAMU_ERR_EOF;
+}
+
+static void stbi_decoder_free(struct camu_decoder **dec)
+{
+ struct camu_stbi_decoder *stb = (struct camu_stbi_decoder *)*dec;
+ al_free(stb);
+ *dec = NULL;
+}
+
+struct camu_demuxer *camu_stbi_demuxer_create(void)
+{
+ struct camu_stbi_demuxer *stb = al_alloc_object(struct camu_stbi_demuxer);
+ stb->demux.type = CAMU_NORMAL;
+ al_array_init(stb->demux.streams);
+ stb->demux.init = stbi_demuxer_init;
+ stb->demux.get_packet = stbi_demuxer_get_packet;
+ stb->demux.get_duration = stbi_demuxer_get_duration;
+ stb->demux.seek = stbi_demuxer_seek;
+ stb->demux.free = stbi_demuxer_free;
+ return (struct camu_demuxer *)stb;
+}
+
+struct camu_decoder *camu_stbi_decoder_create(void)
+{
+ struct camu_stbi_decoder *stb = al_alloc_object(struct camu_stbi_decoder);
+ stb->dec.init = stbi_decoder_init;
+ stb->dec.set_callback = stbi_decoder_set_callback;
+ stb->dec.push = stbi_decoder_push;
+ stb->dec.process = stbi_decoder_process;
+ stb->dec.flush = stbi_decoder_flush;
+ stb->dec.free = stbi_decoder_free;
+ return (struct camu_decoder *)stb;
+}