summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-02-19 18:43:35 -0500
committerpommicket <pommicket@gmail.com>2025-02-19 18:43:35 -0500
commit0b2293a1b44748e494d9db2ae72c72a16b693a9d (patch)
treec3c887ca80398682f4760f9c7f8e8692e2baaa89
parent99ffd21ef873cc30ac37c901ddd374fb26d41939 (diff)
configure image format
-rw-r--r--camera.c8
-rw-r--r--camera.h3
-rw-r--r--main.c42
3 files changed, 48 insertions, 5 deletions
diff --git a/camera.c b/camera.c
index d1448d0..f064073 100644
--- a/camera.c
+++ b/camera.c
@@ -298,12 +298,18 @@ static uint8_t *camera_curr_frame(Camera *camera) {
assert(camera->userp_frames[camera->curr_frame_idx]);
return camera->userp_frames[camera->curr_frame_idx];
}
-void camera_write_jpg(Camera *camera, const char *name, int quality) {
+void camera_save_jpg(Camera *camera, const char *name, int quality) {
uint8_t *frame = camera_curr_frame(camera);
if (frame) {
stbi_write_jpg(name, camera_frame_width(camera), camera_frame_height(camera), 3, frame, quality);
}
}
+void camera_save_png(Camera *camera, const char *name) {
+ uint8_t *frame = camera_curr_frame(camera);
+ if (frame) {
+ stbi_write_png(name, camera_frame_width(camera), camera_frame_height(camera), 3, frame, camera_frame_width(camera) * 3);
+ }
+}
bool camera_next_frame(Camera *camera) {
struct pollfd pollfd = {.fd = camera->fd, .events = POLLIN};
// check whether there is any data available from camera
diff --git a/camera.h b/camera.h
index 00c8c07..4888729 100644
--- a/camera.h
+++ b/camera.h
@@ -103,7 +103,8 @@ PictureFormat camera_closest_resolution(Camera *camera, uint32_t pixfmt, int32_t
int32_t camera_frame_width(Camera *camera);
int32_t camera_frame_height(Camera *camera);
PictureFormat camera_picture_format(Camera *camera);
-void camera_write_jpg(Camera *camera, const char *name, int quality);
+void camera_save_jpg(Camera *camera, const char *path, int quality);
+void camera_save_png(Camera *camera, const char *path);
bool camera_next_frame(Camera *camera);
void camera_update_gl_textures(Camera *camera, const GLuint textures[3]);
const char *camera_name(Camera *camera);
diff --git a/main.c b/main.c
index be956c5..6e7b58d 100644
--- a/main.c
+++ b/main.c
@@ -43,23 +43,35 @@ enum {
MENU_OPT_RESOLUTION,
MENU_OPT_INPUT,
MENU_OPT_PIXFMT,
+ MENU_OPT_IMGFMT,
};
// use char for MenuOption type so that we can use strlen
typedef char MenuOption;
static const MenuOption main_menu[] = {
MENU_OPT_INPUT,
MENU_OPT_RESOLUTION,
+ MENU_OPT_IMGFMT,
MENU_OPT_PIXFMT,
MENU_OPT_QUIT,
0
};
+typedef enum {
+ IMG_FMT_JPEG,
+ IMG_FMT_PNG,
+
+ IMG_FMT_COUNT,
+} ImageFormat;
+static const char *const image_format_names[IMG_FMT_COUNT] = {"JPEG", "PNG"};
+static const char *const image_format_extensions[IMG_FMT_COUNT] = {"jpg", "png"};
+
typedef struct {
Menu curr_menu;
int menu_sel[MENU_COUNT];
bool show_fps;
Camera *camera;
Camera **cameras;
+ ImageFormat image_format;
} State;
#if crypto_generichash_BYTES_MIN > HASH_SIZE
@@ -516,9 +528,20 @@ void main() {\n\
case SDLK_SPACE: {
time_t t = time(NULL);
struct tm *tm = localtime(&t);
- char name[256];
- strftime(name, sizeof name, "%Y-%m-%d-%H-%M-%S.jpg", tm);
- camera_write_jpg(state->camera, name, 90);
+ static char name[64];
+ strftime(name, sizeof name, "%Y-%m-%d-%H-%M-%S", tm);
+ sprintf(name + strlen(name), ".%s", image_format_extensions[state->image_format]);
+ switch (state->image_format) {
+ case IMG_FMT_JPEG:
+ camera_save_jpg(state->camera, name, 90);
+ break;
+ case IMG_FMT_PNG:
+ camera_save_png(state->camera, name);
+ break;
+ case IMG_FMT_COUNT:
+ assert(false);
+ break;
+ }
} break;
case SDLK_ESCAPE:
if (state->curr_menu == MENU_NONE) {
@@ -551,6 +574,12 @@ void main() {\n\
case SDLK_F2:
state->show_fps = !state->show_fps;
break;
+ case SDLK_LEFT:
+ if (state->curr_menu == MENU_MAIN && state->menu_sel[MENU_MAIN] == MENU_OPT_IMGFMT) {
+ state->image_format = state->image_format == 0 ? IMG_FMT_COUNT - 1 : state->image_format - 1;
+ menu_needs_rerendering = true;
+ }
+ break;
case SDLK_RIGHT:
case SDLK_RETURN:
if (state->curr_menu == MENU_MAIN) {
@@ -594,6 +623,10 @@ void main() {\n\
}
arr_free(pixfmts);
} break;
+ case MENU_OPT_IMGFMT: {
+ state->image_format = (state->image_format + 1) % IMG_FMT_COUNT;
+ menu_needs_rerendering = true;
+ } break;
}
} else if (state->curr_menu == MENU_RESOLUTION) {
PictureFormat *resolutions = camera_get_resolutions_with_pixfmt(state->camera, camera_pixel_format(state->camera));
@@ -685,6 +718,9 @@ void main() {\n\
state->camera ? pixfmt_to_string(camera_pixel_format(state->camera))
: "None");
break;
+ case MENU_OPT_IMGFMT:
+ option = a_sprintf("Image format: %s", image_format_names[state->image_format]);
+ break;
default:
assert(false);
option = strdup("???");