Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix data to use managed memory instead of naked pointer #96

Merged
merged 1 commit into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions io/jpg/Jpg.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ open Bigarray
type data = (int32, int32_elt, c_layout) Array1.t

module IO = struct
type buffer
type t = { data : data; buffer : buffer }
type t = { data : data }

let loadImage filename : t Odiff.ImageIO.img =
let width, height, data, buffer = ReadJpg.read_jpeg_image filename in
{ width; height; image = { data; buffer } }
let width, height, data = ReadJpg.read_jpeg_image filename in
{ width; height; image = { data } }

let readDirectPixel ~x ~y (img : t Odiff.ImageIO.img) =
Array1.unsafe_get img.image.data ((y * img.width) + x)
Expand All @@ -19,10 +18,9 @@ module IO = struct
let saveImage (img : t Odiff.ImageIO.img) filename =
WritePng.write_png_bigarray filename img.image.data img.width img.height

let freeImage (img : t Odiff.ImageIO.img) =
ReadJpg.cleanup_jpg img.image.buffer
let freeImage (img : t Odiff.ImageIO.img) = ()

let makeSameAsLayout (img : t Odiff.ImageIO.img) =
let data = Array1.create int32 c_layout (Array1.dim img.image.data) in
{ img with image = { data; buffer = img.image.buffer } }
{ img with image = { data } }
end
28 changes: 10 additions & 18 deletions io/jpg/ReadJpg.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ read_jpeg_file_to_tuple(value file)
caml_failwith("opening input file failed!");
}
if (fseek(fp, 0, SEEK_END) < 0 || ((size = ftell(fp)) < 0) || fseek(fp, 0, SEEK_SET) < 0) {
fclose(fp);
caml_failwith("determining input file size failed");
}
if (size == 0) {
fclose(fp);
caml_failwith("Input file contains no data");
}

Expand All @@ -46,10 +48,12 @@ read_jpeg_file_to_tuple(value file)
JDIMENSION stride = width * channels;
JSAMPARRAY temp_buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, stride, 1);

int buffer_size = width * height;
uint8_t *image_buffer = (uint8_t*)malloc(buffer_size * 4);
int buffer_size = width * height * 4;
intnat dims[1] = {buffer_size};
ba = caml_ba_alloc(CAML_BA_UINT8 | CAML_BA_C_LAYOUT | CAML_BA_MANAGED, 1, NULL, dims);
uint8_t *image_buffer = (uint8_t *)Caml_ba_data_val(ba);

while (cinfo.output_scanline < cinfo.output_height) {
while (cinfo.output_scanline < height) {
jpeg_read_scanlines(&cinfo, temp_buffer, 1);

unsigned int k = (cinfo.output_scanline - 1) * 4 * width;
Expand All @@ -65,25 +69,13 @@ read_jpeg_file_to_tuple(value file)
}

jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(fp);

res = caml_alloc(4, 0);
ba = caml_ba_alloc_dims(CAML_BA_INT32 | CAML_BA_C_LAYOUT, 1, image_buffer, buffer_size);

res = caml_alloc_tuple(3);
Store_field(res, 0, Val_int(width));
Store_field(res, 1, Val_int(height));
Store_field(res, 2, ba);
Store_field(res, 3, Val_bp(image_buffer));

jpeg_destroy_decompress(&cinfo);
fclose(fp);

CAMLreturn(res);
}

CAMLprim value
cleanup_jpg(value buffer)
{
CAMLparam1(buffer);
free(Bp_val(buffer));
CAMLreturn(Val_unit);
}
8 changes: 2 additions & 6 deletions io/jpg/ReadJpg.ml
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
external read_jpeg_image :
string ->
int
* int
* (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array1.t
* 'a = "read_jpeg_file_to_tuple"

external cleanup_jpg : 'a -> unit = "cleanup_jpg" [@@noalloc]
int * int * (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array1.t
= "read_jpeg_file_to_tuple"
2 changes: 1 addition & 1 deletion io/png/Png.ml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module IO : Odiff.ImageIO.ImageIO = struct
Array1.unsafe_set image ((y * img.width) + x) color

let loadImage filename : t Odiff.ImageIO.img =
let width, height, data, _buffer = ReadPng.read_png_image filename in
let width, height, data = ReadPng.read_png_image filename in
{ width; height; image = data }

let saveImage (img : t Odiff.ImageIO.img) filename =
Expand Down
28 changes: 11 additions & 17 deletions io/png/ReadPng.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ CAMLprim value read_png_file(value file) {
int result = 0;
FILE *png;
spng_ctx *ctx = NULL;
unsigned char *out = NULL;
const char *filename = String_val(file);

png = fopen(filename, "rb");
Expand All @@ -24,11 +23,9 @@ CAMLprim value read_png_file(value file) {
}

ctx = spng_ctx_new(0);

if (ctx == NULL) {
fclose(png);
caml_failwith("spng_ctx_new() failed");
spng_ctx_free(ctx);
free(out);
}

/* Ignore and don't calculate chunk CRC's */
Expand All @@ -46,40 +43,37 @@ CAMLprim value read_png_file(value file) {
result = spng_get_ihdr(ctx, &ihdr);

if (result) {
caml_failwith("spng_get_ihdr() error!");
spng_ctx_free(ctx);
free(out);
fclose(png);
caml_failwith("spng_get_ihdr() error!");
}

size_t out_size;
result = spng_decoded_image_size(ctx, SPNG_FMT_RGBA8, &out_size);
if (result) {
spng_ctx_free(ctx);
fclose(png);
caml_failwith(spng_strerror(result));
};

out = malloc(out_size);
if (out == NULL) {
spng_ctx_free(ctx);
free(out);
};
ba = caml_ba_alloc(CAML_BA_UINT8 | CAML_BA_C_LAYOUT | CAML_BA_MANAGED, 1, NULL, &out_size);
unsigned char *out = (unsigned char *)Caml_ba_data_val(ba);

result =
spng_decode_image(ctx, out, out_size, SPNG_FMT_RGBA8, SPNG_DECODE_TRNS);
if (result) {
spng_ctx_free(ctx);
free(out);
fclose(png);
caml_failwith(spng_strerror(result));
}

res = caml_alloc(4, 0);
ba = caml_ba_alloc_dims(CAML_BA_INT32 | CAML_BA_C_LAYOUT, 1, out, out_size);
spng_ctx_free(ctx);
fclose(png);

res = caml_alloc_tuple(3);
Store_field(res, 0, Val_int(ihdr.width));
Store_field(res, 1, Val_int(ihdr.height));
Store_field(res, 2, ba);
Store_field(res, 3, Val_bp(out));

spng_ctx_free(ctx);

CAMLreturn(res);
}
6 changes: 2 additions & 4 deletions io/png/ReadPng.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
external read_png_image :
string ->
int
* int
* (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array1.t
* 'a = "read_png_file"
int * int * (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array1.t
= "read_png_file"
23 changes: 5 additions & 18 deletions io/tiff/ReadTiff.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ CAMLprim value read_tiff_file_to_tuple(value file) {
CAMLlocal2(res, ba);

const char *filename = String_val(file);
uint32_t *buffer = NULL;
int width;
int height;

Expand All @@ -29,35 +28,23 @@ CAMLprim value read_tiff_file_to_tuple(value file) {
TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);

int buffer_size = width * height;
buffer = (uint32_t *)malloc(buffer_size * 4);

if (!buffer) {
TIFFClose(image);
caml_failwith("allocating TIFF buffer failed");
}
intnat dims[1] = {buffer_size};
ba = caml_ba_alloc(CAML_BA_INT32 | CAML_BA_C_LAYOUT | CAML_BA_MANAGED, 1, NULL, dims);

uint32_t *buffer = (uint32_t *)Caml_ba_data_val(ba);
if (!(TIFFReadRGBAImageOriented(image, width, height, buffer,
ORIENTATION_TOPLEFT, 0))) {
TIFFClose(image);
caml_failwith("reading input file failed");
}

res = caml_alloc(4, 0);
ba = caml_ba_alloc_dims(CAML_BA_INT32 | CAML_BA_C_LAYOUT, 1, buffer,
buffer_size);
TIFFClose(image);

res = caml_alloc_tuple(3);
Store_field(res, 0, Val_int(width));
Store_field(res, 1, Val_int(height));
Store_field(res, 2, ba);
Store_field(res, 3, Val_bp(buffer));

TIFFClose(image);

CAMLreturn(res);
}

CAMLprim value cleanup_tiff(value buffer) {
CAMLparam1(buffer);
free(Bp_val(buffer));
CAMLreturn(Val_unit);
}
8 changes: 2 additions & 6 deletions io/tiff/ReadTiff.ml
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
external load :
string ->
int
* int
* (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array1.t
* 'a = "read_tiff_file_to_tuple"

external cleanup_tiff : 'a -> unit = "cleanup_tiff" [@@noalloc]
int * int * (int32, Bigarray.int32_elt, Bigarray.c_layout) Bigarray.Array1.t
= "read_tiff_file_to_tuple"
11 changes: 5 additions & 6 deletions io/tiff/Tiff.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ type data = (int32, int32_elt, c_layout) Array1.t

module IO : Odiff.ImageIO.ImageIO = struct
type buffer
type t = { data : data; buffer : buffer }
type t = { data : data }

let loadImage filename : t Odiff.ImageIO.img =
let width, height, data, buffer = ReadTiff.load filename in
{ width; height; image = { data; buffer } }
let width, height, data = ReadTiff.load filename in
{ width; height; image = { data } }

let readDirectPixel ~(x : int) ~(y : int) (img : t Odiff.ImageIO.img) =
Array1.unsafe_get img.image.data ((y * img.width) + x)
Expand All @@ -19,10 +19,9 @@ module IO : Odiff.ImageIO.ImageIO = struct
let saveImage (img : t Odiff.ImageIO.img) filename =
WritePng.write_png_bigarray filename img.image.data img.width img.height

let freeImage (img : t Odiff.ImageIO.img) =
ReadTiff.cleanup_tiff img.image.buffer
let freeImage (img : t Odiff.ImageIO.img) = ()

let makeSameAsLayout (img : t Odiff.ImageIO.img) =
let data = Array1.create int32 c_layout (Array1.dim img.image.data) in
{ img with image = { data; buffer = img.image.buffer } }
{ img with image = { data } }
end