Read bits per sample
This commit is contained in:
parent
f0d4108a64
commit
38862899d0
@ -39,6 +39,9 @@
|
|||||||
#define TIFF_SHORT_BYTE_COUNT field_types[TIFF_FIELD_TYPE_SHORT].byte_count
|
#define TIFF_SHORT_BYTE_COUNT field_types[TIFF_FIELD_TYPE_SHORT].byte_count
|
||||||
#define TIFF_LONG_BYTE_COUNT field_types[TIFF_FIELD_TYPE_LONG].byte_count
|
#define TIFF_LONG_BYTE_COUNT field_types[TIFF_FIELD_TYPE_LONG].byte_count
|
||||||
|
|
||||||
|
#define RGB_SAMPLE_COUNT 3
|
||||||
|
#define MINIMUM_BITS_PER_SAMPLE 8
|
||||||
|
|
||||||
#define TEMP_ARENA_CAPACITY (20 * 1024 * 1024)
|
#define TEMP_ARENA_CAPACITY (20 * 1024 * 1024)
|
||||||
|
|
||||||
typedef struct tiff_reader TiffReader;
|
typedef struct tiff_reader TiffReader;
|
||||||
@ -63,6 +66,8 @@ internal TiffHdr read_tiff_header(const TiffReader *reader);
|
|||||||
internal TiffIFD read_ifd(const TiffReader *reader, Arena *arena);
|
internal TiffIFD read_ifd(const TiffReader *reader, Arena *arena);
|
||||||
internal TiffImage read_ifd_fields(const TiffReader *reader);
|
internal TiffImage read_ifd_fields(const TiffReader *reader);
|
||||||
internal TiffAlpha read_alpha(const TiffReader *reader, TiffImage *img);
|
internal TiffAlpha read_alpha(const TiffReader *reader, TiffImage *img);
|
||||||
|
internal TiffSampleBits read_bits_per_sample(const TiffReader *reader,
|
||||||
|
TiffImage *img);
|
||||||
internal Pixel *load_image_pixels(TiffReader *reader, Arena *arena);
|
internal Pixel *load_image_pixels(TiffReader *reader, Arena *arena);
|
||||||
internal bool read_strip_data(TiffReader *reader, Arena *arena);
|
internal bool read_strip_data(TiffReader *reader, Arena *arena);
|
||||||
internal void read_strips(const TiffReader *reader, Pixel *buf);
|
internal void read_strips(const TiffReader *reader, Pixel *buf);
|
||||||
@ -127,6 +132,11 @@ Image *read_baseline_tiff(const char *file, Arena *arena) {
|
|||||||
|
|
||||||
assert((reader.img.type == TIFF_IMAGE_TYPE_RGB) &&
|
assert((reader.img.type == TIFF_IMAGE_TYPE_RGB) &&
|
||||||
"Currently, only RGB images are supported");
|
"Currently, only RGB images are supported");
|
||||||
|
assert((reader.img.rgba_bits_per_sample.r == MINIMUM_BITS_PER_SAMPLE &&
|
||||||
|
reader.img.rgba_bits_per_sample.g == MINIMUM_BITS_PER_SAMPLE &&
|
||||||
|
reader.img.rgba_bits_per_sample.b == MINIMUM_BITS_PER_SAMPLE &&
|
||||||
|
reader.img.rgba_bits_per_sample.a == MINIMUM_BITS_PER_SAMPLE) &&
|
||||||
|
"Currently, only 8-bit images are supported");
|
||||||
|
|
||||||
reader.pixels = load_image_pixels(&reader, temp_arena);
|
reader.pixels = load_image_pixels(&reader, temp_arena);
|
||||||
if (!reader.pixels) {
|
if (!reader.pixels) {
|
||||||
@ -258,6 +268,7 @@ internal TiffImage read_ifd_fields(const TiffReader *reader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
img_out.alpha = read_alpha(reader, &img_out);
|
img_out.alpha = read_alpha(reader, &img_out);
|
||||||
|
img_out.rgba_bits_per_sample = read_bits_per_sample(reader, &img_out);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@ -302,6 +313,7 @@ internal TiffAlpha read_alpha(const TiffReader *reader, TiffImage *img) {
|
|||||||
alpha.type = *sample == TIFF_EXTRA_SAMPLE_ASSOCIATED_ALPHA
|
alpha.type = *sample == TIFF_EXTRA_SAMPLE_ASSOCIATED_ALPHA
|
||||||
? ALPHA_TYPE_ASSOCIATED
|
? ALPHA_TYPE_ASSOCIATED
|
||||||
: ALPHA_TYPE_UNASSOCIATED;
|
: ALPHA_TYPE_UNASSOCIATED;
|
||||||
|
alpha.sample_offset = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,6 +322,48 @@ READ_ALPHA_RETURN:
|
|||||||
return alpha;
|
return alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal TiffSampleBits read_bits_per_sample(const TiffReader *reader,
|
||||||
|
TiffImage *img) {
|
||||||
|
TiffAlpha alpha = img->alpha;
|
||||||
|
u64 main_samples = img->sample_count - img->extra_samples_count;
|
||||||
|
|
||||||
|
u64 byte_count = TIFF_SHORT_BYTE_COUNT * img->sample_count;
|
||||||
|
u16 bits_per_sample[img->sample_count];
|
||||||
|
memset(bits_per_sample, 0, byte_count);
|
||||||
|
|
||||||
|
if (img->bits_per_sample_offset) {
|
||||||
|
read_from_file_with_offset(reader->fp, bits_per_sample, byte_count,
|
||||||
|
img->bits_per_sample);
|
||||||
|
} else {
|
||||||
|
memcpy(bits_per_sample, &(img->bits_per_sample), byte_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
TiffSampleBits bits = {0};
|
||||||
|
memcpy(&bits, bits_per_sample, TIFF_SHORT_BYTE_COUNT * main_samples);
|
||||||
|
|
||||||
|
if (main_samples < RGB_SAMPLE_COUNT) {
|
||||||
|
u64 count = RGB_SAMPLE_COUNT - main_samples;
|
||||||
|
for (u64 i = 0; i < count; ++i) {
|
||||||
|
u16 *value = &(((u16 *)(&bits))[main_samples + i]);
|
||||||
|
*value = MINIMUM_BITS_PER_SAMPLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alpha.type == ALPHA_TYPE_UNDEFINED) {
|
||||||
|
bits.a = MINIMUM_BITS_PER_SAMPLE;
|
||||||
|
} else {
|
||||||
|
void *alpha_sample = &(bits_per_sample[main_samples + alpha.sample_offset]);
|
||||||
|
memcpy(&(bits.a), alpha_sample, TIFF_SHORT_BYTE_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
bits.r = bits.r < MINIMUM_BITS_PER_SAMPLE ? MINIMUM_BITS_PER_SAMPLE : bits.r;
|
||||||
|
bits.g = bits.g < MINIMUM_BITS_PER_SAMPLE ? MINIMUM_BITS_PER_SAMPLE : bits.g;
|
||||||
|
bits.b = bits.b < MINIMUM_BITS_PER_SAMPLE ? MINIMUM_BITS_PER_SAMPLE : bits.b;
|
||||||
|
bits.a = bits.a < MINIMUM_BITS_PER_SAMPLE ? MINIMUM_BITS_PER_SAMPLE : bits.a;
|
||||||
|
|
||||||
|
return bits;
|
||||||
|
}
|
||||||
|
|
||||||
internal Pixel *load_image_pixels(TiffReader *reader, Arena *arena) {
|
internal Pixel *load_image_pixels(TiffReader *reader, Arena *arena) {
|
||||||
Pixel *buf = NULL;
|
Pixel *buf = NULL;
|
||||||
u64 img_byte_count =
|
u64 img_byte_count =
|
||||||
|
@ -123,6 +123,14 @@ struct tiff_alpha {
|
|||||||
u32 sample_offset;
|
u32 sample_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct tiff_sample_bits TiffSampleBits;
|
||||||
|
struct tiff_sample_bits {
|
||||||
|
u16 r;
|
||||||
|
u16 g;
|
||||||
|
u16 b;
|
||||||
|
u16 a;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct tiff_strip TiffStrip;
|
typedef struct tiff_strip TiffStrip;
|
||||||
struct tiff_strip {
|
struct tiff_strip {
|
||||||
u32 offset;
|
u32 offset;
|
||||||
@ -152,6 +160,7 @@ struct tiff_image {
|
|||||||
u32 extra_samples_count;
|
u32 extra_samples_count;
|
||||||
bool extra_samples_offset;
|
bool extra_samples_offset;
|
||||||
TiffAlpha alpha;
|
TiffAlpha alpha;
|
||||||
|
TiffSampleBits rgba_bits_per_sample;
|
||||||
TiffStrip *strips;
|
TiffStrip *strips;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user