First botched attempt at reading image data :D
This commit is contained in:
parent
0bd448a8a9
commit
8040dd7381
6
compile
6
compile
@ -3,17 +3,19 @@
|
|||||||
CC=clang
|
CC=clang
|
||||||
CFLAGS="-g -Wall -Werror -pedantic -fsanitize=address -fsanitize=undefined"
|
CFLAGS="-g -Wall -Werror -pedantic -fsanitize=address -fsanitize=undefined"
|
||||||
INCLUDES="\
|
INCLUDES="\
|
||||||
-Isrc \
|
-I$(find ./src -type d | xargs -I{} echo -n "-I{} ") \
|
||||||
-Iintern/wizapp/aliases \
|
-Iintern/wizapp/aliases \
|
||||||
-Iintern/wizapp/cpath/include \
|
-Iintern/wizapp/cpath/include \
|
||||||
-Iintern/wizapp/dstr/include \
|
-Iintern/wizapp/dstr/include \
|
||||||
$(find intern/wizapp/mem/include -type d | xargs -I{} echo -n "-I{} ") \
|
$(find intern/wizapp/mem/include -type d | xargs -I{} echo -n "-I{} ") \
|
||||||
|
$(pkg-config --cflags sdl2) \
|
||||||
"
|
"
|
||||||
LIBS="\
|
LIBS="\
|
||||||
-lm \
|
-lm \
|
||||||
|
$(pkg-config --libs sdl2) \
|
||||||
"
|
"
|
||||||
SRC="\
|
SRC="\
|
||||||
./src/*.c \
|
$(find ./src -name *.c | xargs -I{} echo -n "{} ") \
|
||||||
intern/wizapp/cpath/src/*.c \
|
intern/wizapp/cpath/src/*.c \
|
||||||
intern/wizapp/dstr/src/*.c \
|
intern/wizapp/dstr/src/*.c \
|
||||||
intern/wizapp/mem/src/*/*.c \
|
intern/wizapp/mem/src/*/*.c \
|
||||||
|
171
src/main.c
171
src/main.c
@ -1,12 +1,40 @@
|
|||||||
#include "aliases.h"
|
#include "aliases.h"
|
||||||
|
#include "image.h"
|
||||||
#include "mem_allocator.h"
|
#include "mem_allocator.h"
|
||||||
#include "mem_ctx.h"
|
#include "mem_ctx.h"
|
||||||
#include "tiffread.h"
|
#include "tiffread.h"
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_events.h>
|
||||||
|
#include <SDL2/SDL_render.h>
|
||||||
|
#include <SDL2/SDL_surface.h>
|
||||||
|
#include <SDL2/SDL_video.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define WINDOW_WIDTH 800
|
||||||
|
#define WINDOW_HEIGHT 600
|
||||||
|
|
||||||
|
#define AMASK 0xff000000
|
||||||
|
#define BMASK 0x00ff0000
|
||||||
|
#define GMASK 0x0000ff00
|
||||||
|
#define RMASK 0x000000ff
|
||||||
|
|
||||||
|
#define WHITE 0xff
|
||||||
|
|
||||||
|
typedef struct point Point;
|
||||||
|
struct point {
|
||||||
|
u32 x;
|
||||||
|
u32 y;
|
||||||
|
};
|
||||||
|
|
||||||
|
Point point_from_index(u32 index, u32 w);
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
int exit_code = EXIT_SUCCESS;
|
||||||
|
|
||||||
wapp_mem_ctx_init(10 * 1024 * 1024, 2 * 1024 * 1024);
|
wapp_mem_ctx_init(10 * 1024 * 1024, 2 * 1024 * 1024);
|
||||||
Allocator ctx_main_allocator = wapp_mem_ctx_allocator(CTX_DEST_BUFFER_MAIN);
|
Allocator ctx_main_allocator = wapp_mem_ctx_allocator(CTX_DEST_BUFFER_MAIN);
|
||||||
Allocator ctx_temp_allocator = wapp_mem_ctx_allocator(CTX_DEST_BUFFER_TEMP);
|
Allocator ctx_temp_allocator = wapp_mem_ctx_allocator(CTX_DEST_BUFFER_TEMP);
|
||||||
@ -14,41 +42,134 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
const char *file_to_open = argc > 1 ? argv[1] : "./resources/test.tif";
|
const char *file_to_open = argc > 1 ? argv[1] : "./resources/test.tif";
|
||||||
|
|
||||||
read_baseline_tiff(file_to_open, &ctx_main_allocator);
|
Image *img = read_baseline_tiff(file_to_open, &ctx_main_allocator);
|
||||||
|
if (!img) {
|
||||||
|
exit_code = EXIT_FAILURE;
|
||||||
|
goto MAIN_FREE_CONTEXT;
|
||||||
|
}
|
||||||
|
|
||||||
// FILE *fp = fopen(file_to_open, "rb");
|
FILE *out = fopen("test.ppm", "wb");
|
||||||
|
|
||||||
// TiffHdr header;
|
char magic[] = {'P', '6', '\n'};
|
||||||
// fread(&header, sizeof(header), 1, fp);
|
fwrite(magic, sizeof(magic), 1, out);
|
||||||
|
|
||||||
// TiffIFD ifd = {0};
|
char size[128];
|
||||||
|
sprintf(size, "%lu %lu\n", img->width, img->height);
|
||||||
|
u64 size_length = strlen(size);
|
||||||
|
fwrite(size, size_length, 1, out);
|
||||||
|
|
||||||
// printf("ORDER: %04x\n", header.order);
|
char max[] = {'2', '5', '5', '\n'};
|
||||||
// printf("MAGIC: %04x\n", header.magic);
|
fwrite(max, sizeof(max), 1, out);
|
||||||
|
|
||||||
// fseek(fp, header.first_ifd_offset, SEEK_SET);
|
for (u64 i = 0; i < img->buf_length; i += 4) {
|
||||||
|
fwrite(&(img->data[i]), sizeof(u8), 3, out);
|
||||||
|
}
|
||||||
|
|
||||||
// fread(&(ifd.count), sizeof(ifd.count), 1, fp);
|
fclose(out);
|
||||||
|
|
||||||
// printf("COUNT: %u\n", ifd.count);
|
// if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
||||||
|
// exit_code = EXIT_FAILURE;
|
||||||
|
// goto MAIN_FREE_CONTEXT;
|
||||||
|
// };
|
||||||
|
|
||||||
// TiffField fields[ifd.count];
|
// SDL_Window *window =
|
||||||
// memset(fields, 0, sizeof(TiffField) * ifd.count);
|
// SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED,
|
||||||
|
// SDL_WINDOWPOS_CENTERED,
|
||||||
// for (u32 i = 0; i < ifd.count; ++i) {
|
// WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
|
||||||
// fread(fields + i, sizeof(TiffField), 1, fp);
|
// if (!window) {
|
||||||
// printf("ENTRY %02u (%lu)\n", i, ftell(fp));
|
// exit_code = EXIT_FAILURE;
|
||||||
// printf("\t TAG: %04u (%s)\n", fields[i].tag,
|
// goto MAIN_QUIT_SDL;
|
||||||
// tag_names[fields[i].tag] ? tag_names[fields[i].tag] : "UNKNOWN");
|
|
||||||
// printf("\t TYPE: 0x%04x (%s)\n", fields[i].type,
|
|
||||||
// field_types[fields[i].type].name ?
|
|
||||||
// field_types[fields[i].type].name
|
|
||||||
// : "UNKNOWN");
|
|
||||||
// printf("\t COUNT: %04u\n", fields[i].count);
|
|
||||||
// printf("\tVAL/OFF: %04u\n", fields[i].value_offset);
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// SDL_Renderer *renderer = SDL_CreateRenderer(
|
||||||
|
// window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||||
|
// if (!renderer) {
|
||||||
|
// exit_code = EXIT_FAILURE;
|
||||||
|
// goto MAIN_DESTROY_WINDOW;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// SDL_Surface *surface = SDL_CreateRGBSurface(0, img->width, img->height, 32,
|
||||||
|
// RMASK, GMASK, BMASK, AMASK);
|
||||||
|
// if (!surface) {
|
||||||
|
// exit_code = EXIT_FAILURE;
|
||||||
|
// goto MAIN_DESTROY_RENDERER;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// uint64_t surface_length = surface->h * surface->pitch;
|
||||||
|
// printf("%lu\n", surface_length);
|
||||||
|
// printf("%u\n", surface->w * surface->h);
|
||||||
|
|
||||||
|
// SDL_LockSurface(surface);
|
||||||
|
// u64 position = 0;
|
||||||
|
// for (u64 i = 0; i < surface_length; i += surface->pitch) {
|
||||||
|
// memcpy(&(((u32 *)surface->pixels)[i]), &(img->data[position]),
|
||||||
|
// surface->pitch / sizeof(Pixel));
|
||||||
|
|
||||||
|
// position += surface->pitch;
|
||||||
|
// }
|
||||||
|
// SDL_UnlockSurface(surface);
|
||||||
|
|
||||||
|
// SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
|
||||||
|
// if (!texture) {
|
||||||
|
// exit_code = EXIT_FAILURE;
|
||||||
|
// goto MAIN_DESTROY_SURFACE;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// SDL_Rect dest = {
|
||||||
|
// .w = surface->w,
|
||||||
|
// .h = surface->h,
|
||||||
|
// .x = (WINDOW_WIDTH - surface->w) / 2,
|
||||||
|
// .y = (WINDOW_HEIGHT - surface->h) / 2,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// bool running = true;
|
||||||
|
|
||||||
|
// SDL_Event event = {0};
|
||||||
|
|
||||||
|
// while (running) {
|
||||||
|
// while (SDL_PollEvent(&event)) {
|
||||||
|
// switch (event.type) {
|
||||||
|
// case SDL_QUIT:
|
||||||
|
// running = false;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||||
|
|
||||||
|
// SDL_RenderClear(renderer);
|
||||||
|
|
||||||
|
// SDL_RenderCopy(renderer, texture, NULL, &dest);
|
||||||
|
|
||||||
|
// SDL_RenderPresent(renderer);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// SDL_DestroyTexture(texture);
|
||||||
|
|
||||||
|
// MAIN_DESTROY_SURFACE:
|
||||||
|
// SDL_FreeSurface(surface);
|
||||||
|
|
||||||
|
// MAIN_DESTROY_RENDERER:
|
||||||
|
// SDL_DestroyRenderer(renderer);
|
||||||
|
|
||||||
|
// MAIN_DESTROY_WINDOW:
|
||||||
|
// SDL_DestroyWindow(window);
|
||||||
|
|
||||||
|
// MAIN_QUIT_SDL:
|
||||||
|
// SDL_Quit();
|
||||||
|
|
||||||
|
MAIN_FREE_CONTEXT:
|
||||||
wapp_mem_ctx_free();
|
wapp_mem_ctx_free();
|
||||||
|
|
||||||
return 0;
|
return exit_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point point_from_index(u32 index, u32 w) {
|
||||||
|
Point out = {0};
|
||||||
|
|
||||||
|
out.x = index % w;
|
||||||
|
|
||||||
|
out.y = (index - (index % w)) / w;
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
#include "endianness.h"
|
#include "endianness.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "mem_allocator.h"
|
#include "mem_allocator.h"
|
||||||
|
#include "mem_arena.h"
|
||||||
#include "mem_ctx.h"
|
#include "mem_ctx.h"
|
||||||
#include "mem_libc.h"
|
#include "mem_libc.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -24,21 +26,22 @@
|
|||||||
#define NULL_TIFF_IFD ((TiffIFD){0})
|
#define NULL_TIFF_IFD ((TiffIFD){0})
|
||||||
#define IS_NULL_IFD(IFD) (IFD.count == 0)
|
#define IS_NULL_IFD(IFD) (IFD.count == 0)
|
||||||
|
|
||||||
enum tiff_image_types {
|
#define INVALID_STRIP_COUNT 0
|
||||||
TIFF_IMAGE_BILEVEL,
|
|
||||||
TIFF_IMAGE_GRAYSCALE,
|
|
||||||
TIFF_IMAGE_PALETTE,
|
|
||||||
TIFF_IMAGE_RGB,
|
|
||||||
|
|
||||||
COUNT_TIFF_IMAGE,
|
#define INVALID_ALPHA_OFFSET -1
|
||||||
};
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
internal u16 tiff_image_identifiers[COUNT_TIFF_IMAGE] = {
|
enum tiff_image_identifiers {
|
||||||
[TIFF_IMAGE_BILEVEL] = 0,
|
TIFF_IMAGE_BILEVEL = 0,
|
||||||
[TIFF_IMAGE_GRAYSCALE] = TIFF_PUBLIC_TAG_BITS_PER_SAMPLE,
|
TIFF_IMAGE_GRAYSCALE = TIFF_PUBLIC_TAG_BITS_PER_SAMPLE,
|
||||||
[TIFF_IMAGE_PALETTE] = TIFF_PUBLIC_TAG_BITS_PER_SAMPLE | TIFF_PUBLIC_TAG_COLOR_MAP,
|
TIFF_IMAGE_PALETTE = TIFF_PUBLIC_TAG_BITS_PER_SAMPLE | TIFF_PUBLIC_TAG_COLOR_MAP,
|
||||||
[TIFF_IMAGE_RGB] = TIFF_PUBLIC_TAG_BITS_PER_SAMPLE | TIFF_PUBLIC_TAG_SAMPLES_PER_PIXEL,
|
TIFF_IMAGE_RGB = TIFF_PUBLIC_TAG_BITS_PER_SAMPLE | TIFF_PUBLIC_TAG_SAMPLES_PER_PIXEL,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum tiff_extra_samples {
|
||||||
|
TIFF_EXTRA_SAMPLE_UNSPECIFIED = 0x0000,
|
||||||
|
TIFF_EXTRA_SAMPLE_ASSOCIATED_ALPHA = 0x0001,
|
||||||
|
TIFF_EXTRA_SAMPLE_UNASSOCIATED_ALPHA = 0x0002,
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
@ -53,12 +56,12 @@ Image *read_baseline_tiff(const char *file, const Allocator *allocator) {
|
|||||||
Image *img_out = NULL;
|
Image *img_out = NULL;
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
goto RETURN_IMG;
|
goto READ_BASELINE_RETURN_IMG;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 name_length = strlen(file);
|
u64 name_length = strlen(file);
|
||||||
if (name_length < TIFF_FILENAME_MIN_LENGTH) {
|
if (name_length < TIFF_FILENAME_MIN_LENGTH) {
|
||||||
goto RETURN_IMG;
|
goto READ_BASELINE_RETURN_IMG;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *ext = NULL;
|
const char *ext = NULL;
|
||||||
@ -71,17 +74,17 @@ Image *read_baseline_tiff(const char *file, const Allocator *allocator) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ext || !IS_TIFF_EXTENSION(ext)) {
|
if (!ext || !IS_TIFF_EXTENSION(ext)) {
|
||||||
goto RETURN_IMG;
|
goto READ_BASELINE_RETURN_IMG;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *fp = fopen(file, "rb");
|
FILE *fp = fopen(file, "rb");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
goto RETURN_IMG;
|
goto READ_BASELINE_RETURN_IMG;
|
||||||
}
|
}
|
||||||
|
|
||||||
TiffHdr header = read_tiff_header(fp);
|
TiffHdr header = read_tiff_header(fp);
|
||||||
if (IS_NULL_HEADER(header)) {
|
if (IS_NULL_HEADER(header)) {
|
||||||
goto FILE_CLEANUP;
|
goto READ_BASELINE_FILE_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
Allocator alloc;
|
Allocator alloc;
|
||||||
@ -92,12 +95,12 @@ Image *read_baseline_tiff(const char *file, const Allocator *allocator) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TiffIFD ifd = read_ifd(fp, &header, header.first_ifd_offset, &alloc);
|
TiffIFD ifd = read_ifd(fp, &header, header.first_ifd_offset, &alloc);
|
||||||
read_fields(fp, &header, &ifd, &alloc);
|
img_out = read_fields(fp, &header, &ifd, &alloc);
|
||||||
|
|
||||||
FILE_CLEANUP:
|
READ_BASELINE_FILE_CLEANUP:
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
RETURN_IMG:
|
READ_BASELINE_RETURN_IMG:
|
||||||
return img_out;
|
return img_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,8 +189,13 @@ Image *read_fields(FILE *fp, const TiffHdr *header, const TiffIFD *ifd,
|
|||||||
|
|
||||||
u16 samples_per_pixel = 1;
|
u16 samples_per_pixel = 1;
|
||||||
u16 *bits_per_sample = NULL;
|
u16 *bits_per_sample = NULL;
|
||||||
|
u16 extra_samples = 0;
|
||||||
|
bool has_alpha = false;
|
||||||
|
bool associated_alpha = false;
|
||||||
|
i32 alpha_offset =
|
||||||
|
INVALID_ALPHA_OFFSET; // Alpha offset following colour samples
|
||||||
|
|
||||||
u32 strip_count = 1;
|
u32 strip_count = INVALID_STRIP_COUNT;
|
||||||
u8 *strip_offsets = NULL;
|
u8 *strip_offsets = NULL;
|
||||||
u16 strip_offsets_type = TIFF_FIELD_TYPE_LONG;
|
u16 strip_offsets_type = TIFF_FIELD_TYPE_LONG;
|
||||||
u8 *strip_byte_counts = NULL;
|
u8 *strip_byte_counts = NULL;
|
||||||
@ -293,9 +301,16 @@ Image *read_fields(FILE *fp, const TiffHdr *header, const TiffIFD *ifd,
|
|||||||
break;
|
break;
|
||||||
case TIFF_PUBLIC_TAG_STRIP_OFFSETS: {
|
case TIFF_PUBLIC_TAG_STRIP_OFFSETS: {
|
||||||
strip_offsets_type = field->type;
|
strip_offsets_type = field->type;
|
||||||
u16 field_type_byte_count = field_types[strip_offsets_type].byte_count;
|
u16 field_type_byte_count = field_types[field->type].byte_count;
|
||||||
u32 total_byte_count = field->count * field_type_byte_count;
|
u32 total_byte_count = field->count * field_type_byte_count;
|
||||||
strip_count = field->count;
|
|
||||||
|
if (strip_count == INVALID_STRIP_COUNT) {
|
||||||
|
strip_count = field->count;
|
||||||
|
} else {
|
||||||
|
if (strip_count != field->count) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
strip_offsets =
|
strip_offsets =
|
||||||
(u8 *)wapp_mem_ctx_alloc(CTX_DEST_BUFFER_TEMP, total_byte_count);
|
(u8 *)wapp_mem_ctx_alloc(CTX_DEST_BUFFER_TEMP, total_byte_count);
|
||||||
@ -350,9 +365,16 @@ Image *read_fields(FILE *fp, const TiffHdr *header, const TiffIFD *ifd,
|
|||||||
break;
|
break;
|
||||||
case TIFF_PUBLIC_TAG_STRIP_BYTE_COUNTS: {
|
case TIFF_PUBLIC_TAG_STRIP_BYTE_COUNTS: {
|
||||||
strip_byte_counts_type = field->type;
|
strip_byte_counts_type = field->type;
|
||||||
u16 field_type_byte_count = field_types[strip_offsets_type].byte_count;
|
u16 field_type_byte_count = field_types[field->type].byte_count;
|
||||||
u32 total_byte_count = field->count * field_type_byte_count;
|
u32 total_byte_count = field->count * field_type_byte_count;
|
||||||
strip_count = field->count;
|
|
||||||
|
if (strip_count == INVALID_STRIP_COUNT) {
|
||||||
|
strip_count = field->count;
|
||||||
|
} else {
|
||||||
|
if (strip_count != field->count) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
strip_byte_counts =
|
strip_byte_counts =
|
||||||
(u8 *)wapp_mem_ctx_alloc(CTX_DEST_BUFFER_TEMP, total_byte_count);
|
(u8 *)wapp_mem_ctx_alloc(CTX_DEST_BUFFER_TEMP, total_byte_count);
|
||||||
@ -396,52 +418,202 @@ Image *read_fields(FILE *fp, const TiffHdr *header, const TiffIFD *ifd,
|
|||||||
case TIFF_PUBLIC_TAG_COLOR_MAP:
|
case TIFF_PUBLIC_TAG_COLOR_MAP:
|
||||||
identifier |= field->tag;
|
identifier |= field->tag;
|
||||||
break;
|
break;
|
||||||
|
case TIFF_PUBLIC_TAG_EXTRA_SAMPLES: {
|
||||||
|
extra_samples = field->count;
|
||||||
|
u64 byte_count = field->count * sizeof(u16);
|
||||||
|
|
||||||
|
u8 data_buf[byte_count];
|
||||||
|
|
||||||
|
if (byte_count <= 4) {
|
||||||
|
memcpy(data_buf, (void *)&(field->value_offset), byte_count);
|
||||||
|
} else {
|
||||||
|
read_from_file_with_offset(fp, data_buf, byte_count,
|
||||||
|
field->value_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < field->count; ++i) {
|
||||||
|
u16 sample = ((u16 *)&(field->value_offset))[i];
|
||||||
|
|
||||||
|
if (byte_count > 4) {
|
||||||
|
switch (header->order) {
|
||||||
|
case TIFF_ORDER_LITTLE_ENDIAN:
|
||||||
|
if (IS_BIG_ENDIAN) {
|
||||||
|
sample = htons(sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case TIFF_ORDER_BIG_ENDIAN:
|
||||||
|
if (IS_LITTLE_ENDIAN) {
|
||||||
|
sample = ntohs(sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sample > TIFF_EXTRA_SAMPLE_UNASSOCIATED_ALPHA) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sample > TIFF_EXTRA_SAMPLE_UNSPECIFIED) {
|
||||||
|
if (has_alpha) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
has_alpha = true;
|
||||||
|
associated_alpha =
|
||||||
|
sample == TIFF_EXTRA_SAMPLE_ASSOCIATED_ALPHA ? true : false;
|
||||||
|
alpha_offset = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (identifier == tiff_image_identifiers[TIFF_IMAGE_BILEVEL]) {
|
switch (identifier) {
|
||||||
printf("BILEVEL\n");
|
case TIFF_IMAGE_BILEVEL:
|
||||||
} else if (identifier == tiff_image_identifiers[TIFF_IMAGE_GRAYSCALE]) {
|
case TIFF_IMAGE_GRAYSCALE:
|
||||||
printf("GRAYSCALE\n");
|
if (photometric_interpretation >
|
||||||
} else if (identifier == tiff_image_identifiers[TIFF_IMAGE_PALETTE]) {
|
TIFF_PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO) {
|
||||||
printf("PALETTE\n");
|
return NULL;
|
||||||
} else if (identifier == tiff_image_identifiers[TIFF_IMAGE_RGB]) {
|
}
|
||||||
printf("RGB\n");
|
|
||||||
} else {
|
break;
|
||||||
printf("UNKNOWN\n");
|
case TIFF_IMAGE_PALETTE:
|
||||||
|
if (photometric_interpretation !=
|
||||||
|
TIFF_PHOTOMETRIC_INTERPRETATION_RGB_PALETTE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case TIFF_IMAGE_RGB:
|
||||||
|
if (photometric_interpretation != TIFF_PHOTOMETRIC_INTERPRETATION_RGB) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("WIDTH: %lu, HEIGHT: %lu\n", width, height);
|
printf("WIDTH: %lu, HEIGHT: %lu\n", width, height);
|
||||||
printf("SAMPLES: %u\n", samples_per_pixel);
|
printf("SAMPLES: %u\n", samples_per_pixel);
|
||||||
|
printf("EXTRA SAMPLES: %u\n", extra_samples);
|
||||||
|
printf("ALPHA: %s, %s, %d\n", has_alpha ? "HAS ALPHA" : "NO ALPHA",
|
||||||
|
has_alpha && associated_alpha ? "ASSOCIATED"
|
||||||
|
: has_alpha ? "UNASSOCIATED"
|
||||||
|
: "N/A",
|
||||||
|
alpha_offset);
|
||||||
printf("STRIPS: %u\n", strip_count);
|
printf("STRIPS: %u\n", strip_count);
|
||||||
printf("PHOTOMETRIC INTERPRETATION: %u\n", photometric_interpretation);
|
printf("PHOTOMETRIC INTERPRETATION: %u\n", photometric_interpretation);
|
||||||
|
printf("BITS PER SAMPLE: ");
|
||||||
for (u64 i = 0; i < samples_per_pixel; ++i) {
|
for (u64 i = 0; i < samples_per_pixel; ++i) {
|
||||||
printf("%u\n", bits_per_sample[i]);
|
printf("%u ", bits_per_sample[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
if (has_alpha && alpha_offset == INVALID_ALPHA_OFFSET) {
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("OFFSETS: ");
|
Image *img_out = NULL;
|
||||||
|
|
||||||
|
Arena *temp_arena;
|
||||||
|
u64 img_buf_size = width * height * sizeof(Pixel);
|
||||||
|
wapp_mem_arena_init(&temp_arena, img_buf_size * 4);
|
||||||
|
|
||||||
|
u8 *temp_img_buf = wapp_mem_arena_alloc(temp_arena, img_buf_size);
|
||||||
|
if (!temp_img_buf) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 position = 0;
|
||||||
for (u64 i = 0; i < strip_count; ++i) {
|
for (u64 i = 0; i < strip_count; ++i) {
|
||||||
|
u64 offset;
|
||||||
|
u64 count;
|
||||||
|
|
||||||
if (strip_offsets_type == TIFF_FIELD_TYPE_LONG) {
|
if (strip_offsets_type == TIFF_FIELD_TYPE_LONG) {
|
||||||
printf("%u ", ((u32 *)strip_offsets)[i]);
|
offset = ((u32 *)strip_offsets)[i];
|
||||||
} else {
|
} else {
|
||||||
printf("%u ", ((u16 *)strip_offsets)[i]);
|
offset = ((u16 *)strip_offsets)[i];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
printf("COUNTS: ");
|
|
||||||
for (u64 i = 0; i < strip_count; ++i) {
|
|
||||||
if (strip_byte_counts_type == TIFF_FIELD_TYPE_LONG) {
|
if (strip_byte_counts_type == TIFF_FIELD_TYPE_LONG) {
|
||||||
printf("%u ", ((u32 *)strip_byte_counts)[i]);
|
count = ((u32 *)strip_byte_counts)[i];
|
||||||
} else {
|
} else {
|
||||||
printf("%u ", ((u16 *)strip_byte_counts)[i]);
|
count = ((u16 *)strip_byte_counts)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 *strip_data = wapp_mem_arena_alloc(temp_arena, count);
|
||||||
|
read_from_file_with_offset(fp, strip_data, count, offset);
|
||||||
|
|
||||||
|
if (samples_per_pixel == 4 && has_alpha) {
|
||||||
|
memcpy(&(temp_img_buf[position]), strip_data, count);
|
||||||
|
position += count;
|
||||||
|
} else if (samples_per_pixel > 4) {
|
||||||
|
for (u64 j = 0; j < count; ++j) {
|
||||||
|
memcpy(&(temp_img_buf[position]), &(strip_data[j]), 3);
|
||||||
|
j += 3;
|
||||||
|
|
||||||
|
if (has_alpha) {
|
||||||
|
memcpy(&(temp_img_buf[position]), &(strip_data[j + alpha_offset]), 1);
|
||||||
|
j += 1;
|
||||||
|
} else {
|
||||||
|
temp_img_buf[position] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
j += samples_per_pixel - 4;
|
||||||
|
position += 1;
|
||||||
|
}
|
||||||
|
} else if (samples_per_pixel == 3) {
|
||||||
|
if (identifier == TIFF_IMAGE_RGB) {
|
||||||
|
for (u64 j = 0; j < count; ++j) {
|
||||||
|
memcpy(&(temp_img_buf[position]), &(strip_data[j]), 3);
|
||||||
|
j += 3;
|
||||||
|
position += 3;
|
||||||
|
|
||||||
|
temp_img_buf[position++] = 255;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
goto READ_FIELDS_FREE_ARENA;
|
||||||
|
}
|
||||||
|
} else if (samples_per_pixel == 1) {
|
||||||
|
if (identifier == TIFF_IMAGE_RGB) {
|
||||||
|
goto READ_FIELDS_FREE_ARENA;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u64 j = 0; j < count; ++j) {
|
||||||
|
for (u64 k = 0; k < 3; ++k) {
|
||||||
|
memcpy(&(temp_img_buf[position]), &(strip_data[j]), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
j += 1;
|
||||||
|
position += 3;
|
||||||
|
|
||||||
|
if (has_alpha) {
|
||||||
|
memcpy(&(temp_img_buf[position]), &(strip_data[j + alpha_offset]), 1);
|
||||||
|
j += 1;
|
||||||
|
} else {
|
||||||
|
temp_img_buf[position] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
position += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
goto READ_FIELDS_FREE_ARENA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
return NULL;
|
img_out = create_image(width, height, (Pixel *)temp_img_buf, allocator);
|
||||||
|
|
||||||
|
READ_FIELDS_FREE_ARENA:
|
||||||
|
wapp_mem_arena_free(&temp_arena);
|
||||||
|
|
||||||
|
return img_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_from_file_with_offset(FILE *fp, void *dst, u64 count, u64 offset) {
|
void read_from_file_with_offset(FILE *fp, void *dst, u64 count, u64 offset) {
|
Loading…
Reference in New Issue
Block a user