44 jpeg_decompress_struct *cinfo,
int flags,
int max_size,
size_t *r_width,
size_t *r_height);
51 const char magic[2] = {0xFF, 0xD8};
52 if (size <
sizeof(
magic)) {
75 (*cinfo->err->output_message)(cinfo);
112 src->
pub.bytes_in_buffer = 2;
114 src->
terminal[1] = (JOCTET)JPEG_EOI;
125 size_t skip_size = size_t(num_bytes) <= src->
pub.bytes_in_buffer ? num_bytes :
126 src->
pub.bytes_in_buffer;
128 src->
pub.next_input_byte = src->
pub.next_input_byte + skip_size;
129 src->
pub.bytes_in_buffer = src->
pub.bytes_in_buffer - skip_size;
142 if (cinfo->src ==
nullptr) {
143 cinfo->src = (jpeg_source_mgr *)(*cinfo->mem->alloc_small)(
144 (j_common_ptr)cinfo, JPOOL_PERMANENT,
sizeof(
my_source_mgr));
151 src->
pub.resync_to_restart = jpeg_resync_to_restart;
154 src->
pub.bytes_in_buffer =
size;
155 src->
pub.next_input_byte = buffer;
161#define MAKESTMT(stuff) \
166#define INPUT_VARS(cinfo) \
167 jpeg_source_mgr *datasrc = (cinfo)->src; \
168 const JOCTET *next_input_byte = datasrc->next_input_byte; \
169 size_t bytes_in_buffer = datasrc->bytes_in_buffer
172#define INPUT_SYNC(cinfo) \
173 (datasrc->next_input_byte = next_input_byte, datasrc->bytes_in_buffer = bytes_in_buffer)
176#define INPUT_RELOAD(cinfo) \
177 (next_input_byte = datasrc->next_input_byte, bytes_in_buffer = datasrc->bytes_in_buffer)
183#define MAKE_BYTE_AVAIL(cinfo, action) \
184 if (bytes_in_buffer == 0) { \
185 if (!(*datasrc->fill_input_buffer)(cinfo)) { \
188 INPUT_RELOAD(cinfo); \
195#define INPUT_BYTE(cinfo, V, action) \
196 MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); bytes_in_buffer--; V = GETJOCTET(*next_input_byte++);)
201#define INPUT_2BYTES(cinfo, V, action) \
202 MAKESTMT(MAKE_BYTE_AVAIL(cinfo, action); bytes_in_buffer--; \
203 V = uint(GETJOCTET(*next_input_byte++)) << 8; \
204 MAKE_BYTE_AVAIL(cinfo, action); \
206 V += GETJOCTET(*next_input_byte++);)
228 for (i = 0; i <
length; i++) {
239 (*cinfo->src->skip_input_data)(cinfo, length);
245 jpeg_decompress_struct *cinfo,
int flags,
int max_size,
size_t *r_width,
size_t *r_height)
247 JSAMPARRAY row_pointer;
248 JSAMPLE *buffer =
nullptr;
250 int x,
y, depth, r, g,
b, k;
251 ImBuf *ibuf =
nullptr;
253 jpeg_saved_marker_ptr marker;
254 char *
str, *key, *value;
258 jpeg_set_marker_processor(cinfo, 0xe1,
handle_app1);
259 cinfo->dct_method = JDCT_FLOAT;
260 jpeg_save_markers(cinfo, JPEG_COM, 0xffff);
262 if (jpeg_read_header(cinfo,
false) == JPEG_HEADER_OK) {
263 depth = cinfo->num_components;
265 if (cinfo->jpeg_color_space == JCS_YCCK) {
266 cinfo->out_color_space = JCS_CMYK;
270 *r_width = cinfo->image_width;
273 *r_height = cinfo->image_height;
279 float scale =
float(max_size) / std::max(cinfo->image_width, cinfo->image_height);
280 cinfo->scale_denom = 8;
281 cinfo->scale_num =
max_uu(1,
min_uu(8, ceill(scale *
float(cinfo->scale_denom))));
282 cinfo->dct_method = JDCT_FASTEST;
283 cinfo->dither_mode = JDITHER_ORDERED;
286 jpeg_start_decompress(cinfo);
288 x = cinfo->output_width;
289 y = cinfo->output_height;
292 jpeg_abort_decompress(cinfo);
298 jpeg_abort_decompress(cinfo);
301 row_stride = cinfo->output_width * depth;
303 row_pointer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo, JPOOL_IMAGE, row_stride, 1);
305 for (y = ibuf->
y - 1; y >= 0; y--) {
306 jpeg_read_scanlines(cinfo, row_pointer, 1);
308 buffer = row_pointer[0];
312 for (x = ibuf->
x; x > 0; x--) {
314 rect[0] = rect[1] = rect[2] = *buffer++;
319 for (x = ibuf->
x; x > 0; x--) {
328 for (x = ibuf->
x; x > 0; x--) {
348 marker = cinfo->marker_list;
350 if (marker->marker != JPEG_COM) {
351 goto next_stamp_marker;
361 BLI_strnlen((
const char *)marker->data, marker->data_length));
386 goto next_stamp_marker;
389 key = strchr(
str,
':');
397 goto next_stamp_marker;
401 value = strchr(key,
':');
404 goto next_stamp_marker;
414 marker = marker->next;
417 jpeg_finish_decompress(cinfo);
422 if (cinfo->density_unit == 1) {
424 ibuf->
ppm[0] =
double(cinfo->X_density) / 0.0254;
425 ibuf->
ppm[1] =
double(cinfo->Y_density) / 0.0254;
427 else if (cinfo->density_unit == 2) {
428 ibuf->
ppm[0] =
double(cinfo->X_density) * 100.0;
429 ibuf->
ppm[1] =
double(cinfo->Y_density) * 100.0;
435 jpeg_destroy((j_common_ptr)cinfo);
443 jpeg_decompress_struct _cinfo, *cinfo = &_cinfo;
453 cinfo->err = jpeg_std_error(&jerr.
pub);
461 jpeg_destroy_decompress(cinfo);
465 jpeg_create_decompress(cinfo);
474#define JPEG_MARKER_MSB (0xFF)
475#define JPEG_MARKER_SOI (0xD8)
476#define JPEG_MARKER_APP1 (0xE1)
477#define JPEG_APP1_MAX (1 << 16)
481 const size_t max_thumb_size,
486 jpeg_decompress_struct _cinfo, *cinfo = &_cinfo;
488 FILE *infile =
nullptr;
492 cinfo->err = jpeg_std_error(&jerr.
pub);
500 jpeg_destroy_decompress(cinfo);
504 if ((infile =
BLI_fopen(filepath,
"rb")) ==
nullptr) {
505 fprintf(stderr,
"can't open %s\n", filepath);
518 !feof(infile) && i--)
521 if (i > 0 && !feof(infile)) {
523 ImBuf *ibuf =
nullptr;
541 fseek(infile, 0, SEEK_SET);
542 jpeg_create_decompress(cinfo);
544 jpeg_stdio_src(cinfo, infile);
551#undef JPEG_MARKER_MSB
552#undef JPEG_MARKER_SOI
553#undef JPEG_MARKER_APP1
558 JSAMPLE *buffer =
nullptr;
559 JSAMPROW row_pointer[1];
565 jpeg_start_compress(cinfo,
true);
569 memset(neogeo_word, 0,
sizeof(*neogeo_word));
571 jpeg_write_marker(cinfo, 0xe1, (JOCTET *)neogeo, 10);
575 char static_text[1024];
576 const int static_text_size =
ARRAY_SIZE(static_text);
580 if (
STREQ(prop->name,
"None")) {
581 jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *)
IDP_String(prop), prop->len);
584 char *text = static_text;
585 int text_size = static_text_size;
589 const int text_length_required = 7 + 2 + strlen(prop->name) + strlen(
IDP_String(prop)) + 1;
590 if (text_length_required <= static_text_size) {
591 text =
static_cast<char *
>(
MEM_mallocN(text_length_required,
"jpeg metadata field"));
592 text_size = text_length_required;
605 text, text_size,
"Blender:%s:%s", prop->name,
IDP_String(prop));
607 jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *)text, text_len);
612 if (text != static_text) {
619 row_pointer[0] =
static_cast<JSAMPROW
>(
MEM_mallocN(
620 sizeof(JSAMPLE) * cinfo->input_components * cinfo->image_width,
"jpeg row_pointer"));
622 for (y = ibuf->
y - 1; y >= 0; y--) {
624 buffer = row_pointer[0];
626 switch (cinfo->in_color_space) {
628 for (x = 0; x < ibuf->
x; x++) {
636 for (x = 0; x < ibuf->
x; x++) {
642 memcpy(buffer, rect, 4 * ibuf->
x);
650 jpeg_write_scanlines(cinfo, row_pointer, 1);
653 jpeg_finish_compress(cinfo);
669 jpeg_create_compress(cinfo);
670 jpeg_stdio_dest(cinfo, outfile);
672 cinfo->image_width = ibuf->
x;
673 cinfo->image_height = ibuf->
y;
675 cinfo->in_color_space = JCS_RGB;
677 cinfo->in_color_space = JCS_GRAYSCALE;
684 cinfo->in_color_space = JCS_UNKNOWN;
687 switch (cinfo->in_color_space) {
689 cinfo->input_components = 3;
692 cinfo->input_components = 1;
695 cinfo->input_components = 4;
702 jpeg_set_defaults(cinfo);
706 cinfo->dct_method = JDCT_FLOAT;
707 jpeg_set_quality(cinfo, quality,
true);
715 jpeg_compress_struct _cinfo, *cinfo = &_cinfo;
718 if ((outfile =
BLI_fopen(filepath,
"wb")) ==
nullptr) {
722 cinfo->err = jpeg_std_error(&jerr.
pub);
730 jpeg_destroy_compress(cinfo);
741 jpeg_destroy_compress(cinfo);
#define BLI_STATIC_ASSERT(a, msg)
File and directory operations.
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define LISTBASE_FOREACH(type, var, list)
MINLINE uint min_uu(uint a, uint b)
MINLINE uint max_uu(uint a, uint b)
#define STRNCPY(dst, src)
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
size_t BLI_snprintf_rlen(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
typedef double(DMatrix)[4][4]
ID and Library types, which are fundamental for SDNA.
@ COLOR_ROLE_DEFAULT_BYTE
Contains defines and structs used throughout the imbuf module.
@ IB_uninitialized_pixels
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
void colorspace_set_default_role(char *colorspace, int size, int role)
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
struct ImBuf * IMB_allocImBuf(unsigned int, unsigned int, unsigned char, unsigned int)
#define INPUT_BYTE(cinfo, V, action)
static const uchar jpeg_default_quality
bool imb_is_a_jpeg(const uchar *mem, const size_t size)
static void memory_source(j_decompress_ptr cinfo, const uchar *buffer, size_t size)
my_source_mgr * my_src_ptr
bool imb_savejpeg(ImBuf *ibuf, const char *filepath, int flags)
#define INPUT_2BYTES(cinfo, V, action)
#define INPUT_VARS(cinfo)
static int init_jpeg(FILE *outfile, jpeg_compress_struct *cinfo, ImBuf *ibuf)
static ImBuf * ibJpegImageFromCinfo(jpeg_decompress_struct *cinfo, int flags, int max_size, size_t *r_width, size_t *r_height)
static void term_source(j_decompress_ptr cinfo)
ImBuf * imb_thumbnail_jpeg(const char *filepath, const int flags, const size_t max_thumb_size, char colorspace[IM_MAX_SPACE], size_t *r_width, size_t *r_height)
static uchar ibuf_quality
static boolean handle_app1(j_decompress_ptr cinfo)
#define INPUT_SYNC(cinfo)
my_error_mgr * my_error_ptr
static void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
ImBuf * imb_load_jpeg(const uchar *buffer, size_t size, int flags, char colorspace[IM_MAX_SPACE])
static void init_source(j_decompress_ptr cinfo)
static void write_jpeg(jpeg_compress_struct *cinfo, ImBuf *ibuf)
static void jpeg_error(j_common_ptr cinfo) ATTR_NORETURN
static boolean fill_input_buffer(j_decompress_ptr cinfo)
static bool save_stdjpeg(const char *filepath, ImBuf *ibuf)
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ImbFormatOptions foptions
ImBufByteBuffer byte_buffer
static int magic(const Tex *tex, const float texvec[3], TexResult *texres)