90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
# File 'ext/avif/avif.c', line 90
static VALUE avif_decode(VALUE self, VALUE path) {
Check_Type(path, T_STRING);
decode_payload_t payload;
long path_len = RSTRING_LEN(path);
payload.path = malloc(path_len + 1);
if (!payload.path) {
rb_raise(rb_eNoMemError, "Failed to allocate memory for path string");
}
memcpy(payload.path, RSTRING_PTR(path), path_len);
payload.path[path_len] = '\0';
rb_thread_call_without_gvl(decode, &payload, RUBY_UBF_IO, NULL);
if (payload.error_message) {
char *err_msg = payload.error_message;
rb_raise(rb_eRuntimeError, "AVIF decoding failed: %s", err_msg);
free(err_msg);
}
if (payload.result != AVIF_RESULT_OK) {
rb_raise(rb_eRuntimeError, "AVIF decoding failed: %s", avifResultToString(payload.result));
}
size_t pixel_bytes = (size_t)payload.width * payload.height * 4;
VALUE pixel_string = rb_str_new((const char*)payload.pixels, pixel_bytes);
free(payload.pixels);
rb_str_freeze(pixel_string);
VALUE result_array = rb_ary_new_capa(3);
rb_ary_push(result_array, UINT2NUM(payload.width));
rb_ary_push(result_array, UINT2NUM(payload.height));
rb_ary_push(result_array, pixel_string);
rb_ary_freeze(result_array);
return result_array;
}
|