aboutsummaryrefslogtreecommitdiff
path: root/src/image_writer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/image_writer.c')
-rw-r--r--src/image_writer.c77
1 files changed, 44 insertions, 33 deletions
diff --git a/src/image_writer.c b/src/image_writer.c
index d01a66c..3b4b24a 100644
--- a/src/image_writer.c
+++ b/src/image_writer.c
@@ -1,5 +1,6 @@
#include "../include/image_writer.h"
#include "../include/egl.h"
+#include "../include/utils.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "../external/stb_image_write.h"
@@ -9,29 +10,14 @@
#include <stdio.h>
#include <assert.h>
-static unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal_format, unsigned int format) {
- unsigned int texture_id = 0;
- egl->glGenTextures(1, &texture_id);
- egl->glBindTexture(GL_TEXTURE_2D, texture_id);
- egl->glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
-
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- egl->glBindTexture(GL_TEXTURE_2D, 0);
- return texture_id;
-}
-
/* TODO: Support hdr/10-bit */
-bool gsr_image_writer_init(gsr_image_writer *self, gsr_image_writer_source source, gsr_egl *egl, int width, int height) {
- assert(source == GSR_IMAGE_WRITER_SOURCE_OPENGL);
- self->source = source;
+bool gsr_image_writer_init_opengl(gsr_image_writer *self, gsr_egl *egl, int width, int height) {
+ memset(self, 0, sizeof(*self));
+ self->source = GSR_IMAGE_WRITER_SOURCE_OPENGL;
self->egl = egl;
self->width = width;
self->height = height;
- self->texture = gl_create_texture(self->egl, self->width, self->height, GL_RGB8, GL_RGB); /* TODO: use GL_RGB16 instead of GL_RGB8 for hdr/10-bit */
+ self->texture = gl_create_texture(self->egl, self->width, self->height, GL_RGB8, GL_RGB, GL_LINEAR); /* TODO: use GL_RGB16 instead of GL_RGB8 for hdr/10-bit */
if(self->texture == 0) {
fprintf(stderr, "gsr error: gsr_image_writer_init: failed to create texture\n");
return false;
@@ -39,6 +25,15 @@ bool gsr_image_writer_init(gsr_image_writer *self, gsr_image_writer_source sourc
return true;
}
+bool gsr_image_writer_init_memory(gsr_image_writer *self, const void *memory, int width, int height) {
+ memset(self, 0, sizeof(*self));
+ self->source = GSR_IMAGE_WRITER_SOURCE_OPENGL;
+ self->width = width;
+ self->height = height;
+ self->memory = memory;
+ return true;
+}
+
void gsr_image_writer_deinit(gsr_image_writer *self) {
if(self->texture) {
self->egl->glDeleteTextures(1, &self->texture);
@@ -46,12 +41,30 @@ void gsr_image_writer_deinit(gsr_image_writer *self) {
}
}
-bool gsr_image_writer_write_to_file(gsr_image_writer *self, const char *filepath, gsr_image_format image_format, int quality) {
+static bool gsr_image_writer_write_memory_to_file(gsr_image_writer *self, const char *filepath, gsr_image_format image_format, int quality, const void *data) {
if(quality < 1)
quality = 1;
else if(quality > 100)
quality = 100;
+ bool success = false;
+ switch(image_format) {
+ case GSR_IMAGE_FORMAT_JPEG:
+ success = stbi_write_jpg(filepath, self->width, self->height, 3, data, quality);
+ break;
+ case GSR_IMAGE_FORMAT_PNG:
+ success = stbi_write_png(filepath, self->width, self->height, 3, data, 0);
+ break;
+ }
+
+ if(!success)
+ fprintf(stderr, "gsr error: gsr_image_writer_write_to_file: failed to write image data to output file %s\n", filepath);
+
+ return success;
+}
+
+static bool gsr_image_writer_write_opengl_texture_to_file(gsr_image_writer *self, const char *filepath, gsr_image_format image_format, int quality) {
+ assert(self->source == GSR_IMAGE_WRITER_SOURCE_OPENGL);
uint8_t *frame_data = malloc(self->width * self->height * 3);
if(!frame_data) {
fprintf(stderr, "gsr error: gsr_image_writer_write_to_file: failed to allocate memory for image frame\n");
@@ -67,19 +80,17 @@ bool gsr_image_writer_write_to_file(gsr_image_writer *self, const char *filepath
self->egl->glFlush();
self->egl->glFinish();
- bool success = false;
- switch(image_format) {
- case GSR_IMAGE_FORMAT_JPEG:
- success = stbi_write_jpg(filepath, self->width, self->height, 3, frame_data, quality);
- break;
- case GSR_IMAGE_FORMAT_PNG:
- success = stbi_write_png(filepath, self->width, self->height, 3, frame_data, 0);
- break;
- }
-
- if(!success)
- fprintf(stderr, "gsr error: gsr_image_writer_write_to_file: failed to write image data to output file %s\n", filepath);
-
+ const bool success = gsr_image_writer_write_memory_to_file(self, filepath, image_format, quality, frame_data);
free(frame_data);
return success;
}
+
+bool gsr_image_writer_write_to_file(gsr_image_writer *self, const char *filepath, gsr_image_format image_format, int quality) {
+ switch(self->source) {
+ case GSR_IMAGE_WRITER_SOURCE_OPENGL:
+ return gsr_image_writer_write_opengl_texture_to_file(self, filepath, image_format, quality);
+ case GSR_IMAGE_WRITER_SOURCE_MEMORY:
+ return gsr_image_writer_write_memory_to_file(self, filepath, image_format, quality, self->memory);
+ }
+ return false;
+}