Compare commits

..

2 Commits

Author SHA1 Message Date
19a87c5c4f Read each strip in a separate thread 2024-05-26 14:55:18 +01:00
dde1cce8e4 Load the image in a separate thread 2024-05-26 14:53:26 +01:00
3 changed files with 92 additions and 85 deletions

39
compile
View File

@@ -1,41 +1,20 @@
#!/bin/bash #!/bin/bash
BUILD_TYPE="debug"
while [[ $# > 0 ]];do
case $1 in
--release)
BUILD_TYPE="release"
shift
;;
*|-*|--*)
echo "Unknown option $1"
exit 1
;;
esac
done
CC=clang CC=clang
CFLAGS="-g -Wall -Werror -pedantic -fsanitize=address -fsanitize=undefined -DDEBUG"
if [[ $BUILD_TYPE == "release" ]]; then
CFLAGS="-O3 -Wall -Werror -pedantic"
else
CFLAGS="-g -Wall -Werror -pedantic -fsanitize=address -fsanitize=undefined -DDEBUG"
fi
INCLUDES="\ INCLUDES="\
-I$(find ./src -type d | xargs -I{} echo -n "-I{} ") \ -I$(find ./src -type d | xargs -I{} echo -n "-I{} ") \
$(find intern/wizapp/src -type d | xargs -I{} echo -n "-I{} ") \ $(find intern/wizapp/src -type d | xargs -I{} echo -n "-I{} ") \
$(pkg-config --cflags sdl2) \ $(pkg-config --cflags sdl2) \
" "
LIBS="\ LIBS="\
-lm \ -lm \
-pthread \ -pthread \
$(pkg-config --libs sdl2) \ $(pkg-config --libs sdl2) \
" "
SRC="\ SRC="\
$(find ./src -name "*.c" | xargs -I{} echo -n "{} ") \ $(find ./src -name "*.c" | xargs -I{} echo -n "{} ") \
$(find intern/wizapp/src -type f -name "*.c" | xargs -I{} echo -n "{} ") \ $(find intern/wizapp/src -type f -name "*.c" | xargs -I{} echo -n "{} ") \
" "
OUT=tiffread OUT=tiffread

View File

@@ -4,7 +4,6 @@
#include "tiffread.h" #include "tiffread.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_events.h> #include <SDL2/SDL_events.h>
#include <SDL2/SDL_rect.h>
#include <SDL2/SDL_render.h> #include <SDL2/SDL_render.h>
#include <SDL2/SDL_surface.h> #include <SDL2/SDL_surface.h>
#include <SDL2/SDL_video.h> #include <SDL2/SDL_video.h>
@@ -19,8 +18,6 @@
#define WINDOW_WIDTH 800 #define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600 #define WINDOW_HEIGHT 600
#define VIEW_AREA_WIDTH 700
#define VIEW_AREA_HEIGHT 500
#define AMASK 0xff000000 #define AMASK 0xff000000
#define BMASK 0x00ff0000 #define BMASK 0x00ff0000
@@ -37,7 +34,6 @@ struct point {
internal void write_debug_ppm6(const Image *img); internal void write_debug_ppm6(const Image *img);
internal void *load_tiff_image(void *args); internal void *load_tiff_image(void *args);
internal SDL_Rect get_dest_rect(SDL_Surface *surface);
typedef struct img_thread_args ImgThreadArgs; typedef struct img_thread_args ImgThreadArgs;
struct img_thread_args { struct img_thread_args {
@@ -94,7 +90,12 @@ int main(int argc, char *argv[]) {
goto MAIN_DESTROY_SURFACE; goto MAIN_DESTROY_SURFACE;
} }
SDL_Rect dest = get_dest_rect(surface); SDL_Rect dest = {
.h = surface->h,
.w = surface->w,
.x = (WINDOW_WIDTH - surface->w) / 2,
.y = (WINDOW_HEIGHT - surface->h) / 2,
};
bool running = true; bool running = true;
@@ -187,16 +188,3 @@ internal void *load_tiff_image(void *args) {
return surface; return surface;
} }
internal SDL_Rect get_dest_rect(SDL_Surface *surface) {
f64 ratio = (f64)(surface->h) / (f64)(surface->w);
u64 width = surface->w <= VIEW_AREA_WIDTH ? surface->w : VIEW_AREA_WIDTH;
u64 height = width * ratio;
return (SDL_Rect){
.w = width,
.h = height,
.x = (WINDOW_WIDTH - width) / 2,
.y = (WINDOW_HEIGHT - height) / 2,
};
}

View File

@@ -210,17 +210,6 @@ struct tiff_reader {
Pixel *pixels; Pixel *pixels;
}; };
typedef struct strip_thread_args StripThreadArgs;
struct strip_thread_args {
FILE *fp;
const TiffStrip *strip;
u64 pixel_count;
u64 samples_per_pixel;
u64 main_samples;
TiffAlpha alpha;
Pixel *pixel_write_start;
};
internal bool read_tiff_header(TiffReader *reader); internal bool read_tiff_header(TiffReader *reader);
internal bool read_ifd(TiffReader *reader, Arena *arena); internal bool read_ifd(TiffReader *reader, Arena *arena);
internal bool read_ifd_fields(TiffReader *reader); internal bool read_ifd_fields(TiffReader *reader);
@@ -598,15 +587,68 @@ internal bool read_strip_data(TiffReader *reader, Arena *arena) {
return true; return true;
} }
// internal void read_strips(TiffReader *reader) {
// u64 position = 0;
// u64 main_samples = reader->img.sample_count -
// reader->img.extra_samples_count; TiffAlpha alpha = reader->img.alpha;
// Pixel *p;
// u64 start_offset;
// u64 alpha_offset;
// for (u64 i = 0; i < reader->img.strip_count; ++i) {
// const TiffStrip *strip = &(reader->img.strips[i]);
// for (u64 j = 0; j < strip->byte_count / reader->img.sample_count; ++j) {
// p = &(reader->pixels[position]);
// start_offset = strip->offset + j * reader->img.sample_count;
// alpha_offset = start_offset + main_samples + alpha.sample_offset;
// fread_with_offset(reader->fp, p, main_samples, start_offset);
// if (alpha.type == ALPHA_TYPE_UNDEFINED) {
// p->a = 255;
// } else {
// fread_with_offset(reader->fp, &(p->a), 1, alpha_offset);
// if (alpha.type == ALPHA_TYPE_UNASSOCIATED) {
// f32 a_norm = u8_normalise(p->a);
// p->r = u8_denormalise(u8_normalise(p->r) * a_norm);
// p->g = u8_denormalise(u8_normalise(p->g) * a_norm);
// p->b = u8_denormalise(u8_normalise(p->b) * a_norm);
// }
// }
// ++position;
// }
// }
// }
typedef struct strip_reader_args StripReaderArgs;
struct strip_reader_args {
FILE *fp;
const TiffStrip *strip;
u64 pixel_count;
u64 samples_per_pixel;
u64 main_samples;
TiffAlpha alpha;
Pixel *pixel_write_start;
};
internal bool read_strips(TiffReader *reader) { internal bool read_strips(TiffReader *reader) {
bool output = true;
u64 position = 0; u64 position = 0;
StripThreadArgs args[reader->img.strip_count]; u64 strips_read = 0;
u64 threads_created = 0;
StripReaderArgs args[reader->img.strip_count];
pthread_t threads[reader->img.strip_count]; pthread_t threads[reader->img.strip_count];
for (u64 i = 0; i < reader->img.strip_count; ++i) { for (u64 i = 0; i < reader->img.strip_count; ++i) {
const TiffStrip *strip = &(reader->img.strips[i]); const TiffStrip *strip = &(reader->img.strips[i]);
u64 pixel_count = strip->byte_count / reader->img.sample_count; u64 pixel_count = strip->byte_count / reader->img.sample_count;
args[i] = (StripThreadArgs){ args[i] = (StripReaderArgs){
.fp = fopen(reader->filename, "rb"), .fp = fopen(reader->filename, "rb"),
.strip = strip, .strip = strip,
.pixel_count = pixel_count, .pixel_count = pixel_count,
@@ -618,47 +660,45 @@ internal bool read_strips(TiffReader *reader) {
}; };
if (!args[i].fp) { if (!args[i].fp) {
for (u64 j = 0; j < i; ++j) { output = false;
fclose(args[j].fp); goto READ_STRIPS_CLOSE_FILES;
}
return false;
} }
position += pixel_count; position += pixel_count;
++strips_read;
} }
for (u64 i = 0; i < reader->img.strip_count; ++i) { for (u64 i = 0; i < reader->img.strip_count; ++i) {
if (pthread_create(&(threads[i]), NULL, read_strip, &(args[i])) != 0) { if (pthread_create(&(threads[i]), NULL, read_strip, (void *)&(args[i])) !=
for (u64 j = 0; j < i; ++j) { 0) {
pthread_cancel(threads[i]); break;
fclose(args[j].fp);
}
// Close the remaining files
for (u64 j = i; j < reader->img.strip_count; ++j) {
fclose(args[j].fp);
}
return false;
} }
++threads_created;
} }
bool image_loaded = true; if (threads_created < reader->img.strip_count) {
for (u64 i = 0; i < strips_read; ++i) {
for (u64 i = 0; i < reader->img.strip_count; ++i) { pthread_cancel(threads[i]);
if (pthread_join(threads[i], NULL) != 0) {
image_loaded = false;
} }
return false;
}
for (u64 i = 0; i < reader->img.strip_count; ++i) {
pthread_join(threads[i], NULL);
}
READ_STRIPS_CLOSE_FILES:
for (u64 i = 0; i < strips_read; ++i) {
fclose(args[i].fp); fclose(args[i].fp);
} }
return image_loaded; return output;
} }
internal void *read_strip(void *arg) { internal void *read_strip(void *arg) {
StripThreadArgs *args = (StripThreadArgs *)arg; StripReaderArgs *args = (StripReaderArgs *)arg;
Pixel *p; Pixel *p;
u64 write_offset = 0; u64 write_offset = 0;