diff options
author | Jörg Frings-Fürst <debian@jff.email> | 2022-02-01 15:24:35 +0100 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff.email> | 2022-02-01 15:24:35 +0100 |
commit | 302276dc1b90cfc972fb726ca94a23b18f4b0088 (patch) | |
tree | 33d99da40fb5fa097fdab5584d7ed550d25a33bb /backend/epsonds-jpeg.c | |
parent | 351b7328520c16730ceb46e5acae16038c42185e (diff) |
New upstream version 1.1.1upstream/1.1.1
Diffstat (limited to 'backend/epsonds-jpeg.c')
-rw-r--r-- | backend/epsonds-jpeg.c | 311 |
1 files changed, 160 insertions, 151 deletions
diff --git a/backend/epsonds-jpeg.c b/backend/epsonds-jpeg.c index 244f442..99ca53a 100644 --- a/backend/epsonds-jpeg.c +++ b/backend/epsonds-jpeg.c @@ -20,19 +20,39 @@ #include "epsonds.h" #include "epsonds-jpeg.h" #include "epsonds-ops.h" +#include <setjmp.h> -#define min(A,B) (((A)<(B)) ? (A) : (B)) +struct my_error_mgr { + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; + +typedef struct my_error_mgr * my_error_ptr; + + +METHODDEF(void) my_error_exit (j_common_ptr cinfo) +{ + + char buffer[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message) (cinfo, buffer); + + DBG(10,"Jpeg decode error [%s]", buffer); +} + +LOCAL(struct jpeg_error_mgr *) jpeg_custom_error (struct my_error_mgr * err) +{ + + struct jpeg_error_mgr* pRet = jpeg_std_error(&(err->pub)); + err->pub.error_exit = my_error_exit; + + return pRet; +} typedef struct { struct jpeg_source_mgr pub; - - epsonds_scanner *s; JOCTET *buffer; - - SANE_Byte *linebuffer; - SANE_Int linebuffer_size; - SANE_Int linebuffer_index; + int length; } epsonds_src_mgr; @@ -50,22 +70,11 @@ METHODDEF(boolean) jpeg_fill_input_buffer(j_decompress_ptr cinfo) { epsonds_src_mgr *src = (epsonds_src_mgr *)cinfo->src; - int avail, size; - - /* read from the scanner or the ring buffer */ - - avail = eds_ring_avail(src->s->current); - if (avail == 0) { - return FALSE; - } - /* read from scanner if no data? */ - size = min(1024, avail); - - eds_ring_read(src->s->current, src->buffer, size); src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = size; + src->pub.bytes_in_buffer = src->length; + DBG(18, "reading from ring buffer, %d left\n", src->length); return TRUE; } @@ -87,140 +96,140 @@ jpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes) } } -SANE_Status -eds_jpeg_start(epsonds_scanner *s) -{ - epsonds_src_mgr *src; - - s->jpeg_cinfo.err = jpeg_std_error(&s->jpeg_err); - - jpeg_create_decompress(&s->jpeg_cinfo); - - s->jpeg_cinfo.src = (struct jpeg_source_mgr *)(*s->jpeg_cinfo.mem->alloc_small)((j_common_ptr)&s->jpeg_cinfo, - JPOOL_PERMANENT, sizeof(epsonds_src_mgr)); - - memset(s->jpeg_cinfo.src, 0x00, sizeof(epsonds_src_mgr)); - - src = (epsonds_src_mgr *)s->jpeg_cinfo.src; - src->s = s; - - src->buffer = (JOCTET *)(*s->jpeg_cinfo.mem->alloc_small)((j_common_ptr)&s->jpeg_cinfo, - JPOOL_PERMANENT, - 1024 * sizeof(JOCTET)); - src->pub.init_source = jpeg_init_source; - src->pub.fill_input_buffer = jpeg_fill_input_buffer; - src->pub.skip_input_data = jpeg_skip_input_data; - src->pub.resync_to_restart = jpeg_resync_to_restart; - src->pub.term_source = jpeg_term_source; - src->pub.bytes_in_buffer = 0; - src->pub.next_input_byte = NULL; - - s->jpeg_header_seen = 0; - - return SANE_STATUS_GOOD; -} - -SANE_Status -eds_jpeg_read_header(epsonds_scanner *s) +void eds_decode_jpeg(epsonds_scanner*s, SANE_Byte *data, SANE_Int size, ring_buffer* ringBuffer, SANE_Int isBackSide, SANE_Int needToConvertBW) { - epsonds_src_mgr *src = (epsonds_src_mgr *)s->jpeg_cinfo.src; - - if (jpeg_read_header(&s->jpeg_cinfo, TRUE)) { - - s->jdst = sanei_jpeg_jinit_write_ppm(&s->jpeg_cinfo); - - if (jpeg_start_decompress(&s->jpeg_cinfo)) { - - int size; - - DBG(3, "%s: w: %d, h: %d, components: %d\n", + struct jpeg_decompress_struct jpeg_cinfo; + struct my_error_mgr jpeg_err; + + { + epsonds_src_mgr *src; + + jpeg_cinfo.err = jpeg_custom_error(&jpeg_err); + + jpeg_create_decompress(&jpeg_cinfo); + + jpeg_cinfo.src = (struct jpeg_source_mgr *)(*jpeg_cinfo.mem->alloc_small)((j_common_ptr)&jpeg_cinfo, + JPOOL_PERMANENT, sizeof(epsonds_src_mgr)); + + memset(jpeg_cinfo.src, 0x00, sizeof(epsonds_src_mgr)); +; + src = (epsonds_src_mgr *)jpeg_cinfo.src; + src->pub.init_source = jpeg_init_source; + src->pub.fill_input_buffer = jpeg_fill_input_buffer; + src->pub.skip_input_data = jpeg_skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; + src->pub.term_source = jpeg_term_source; + src->pub.bytes_in_buffer = 0; + src->pub.next_input_byte = NULL; + src->buffer = (JOCTET*)data; + src->length = size; + } + { + if (jpeg_read_header(&jpeg_cinfo, TRUE)) { + + if (jpeg_start_decompress(&jpeg_cinfo)) { + + DBG(10,"%s: w: %d, h: %d, components: %d\n", __func__, - s->jpeg_cinfo.output_width, s->jpeg_cinfo.output_height, - s->jpeg_cinfo.output_components); - - size = s->jpeg_cinfo.output_width * s->jpeg_cinfo.output_components * 1; - - src->linebuffer = (*s->jpeg_cinfo.mem->alloc_large)((j_common_ptr)&s->jpeg_cinfo, - JPOOL_PERMANENT, size); - - src->linebuffer_size = 0; - src->linebuffer_index = 0; - - s->jpeg_header_seen = 1; - - return SANE_STATUS_GOOD; - - } else { - DBG(0, "%s: decompression failed\n", __func__); - return SANE_STATUS_IO_ERROR; + jpeg_cinfo.output_width, jpeg_cinfo.output_height, + jpeg_cinfo.output_components); + } + } + } + { + int sum = 0; + int bufSize = jpeg_cinfo.output_width * jpeg_cinfo.output_components; + + int monoBufSize = (jpeg_cinfo.output_width + 7)/8; + + JSAMPARRAY scanlines = (jpeg_cinfo.mem->alloc_sarray)((j_common_ptr)&jpeg_cinfo, JPOOL_IMAGE, bufSize, 1); + while (jpeg_cinfo.output_scanline < jpeg_cinfo.output_height) { + int l = jpeg_read_scanlines(&jpeg_cinfo, scanlines, 1); + if (l == 0) { + break; + } + sum += l; + + if (needToConvertBW) + { + SANE_Byte* bytes = scanlines[0]; + + SANE_Int imgPos = 0; + + for (int i = 0; i < monoBufSize; i++) + { + SANE_Byte outByte = 0; + + for(SANE_Int bitIndex = 0; bitIndex < 8 && imgPos < bufSize; bitIndex++) { + //DBG(10,"bytes[imgPos] = %d\n", bytes[imgPos]); + + if(bytes[imgPos] >= 110) { + SANE_Byte bit = 7 - (bitIndex % 8); + outByte |= (1<< bit); + } + imgPos += 1; + } + //DBG(10,"outByte = %d\n", outByte); + eds_ring_write(ringBuffer, &outByte, 1); + } + } + else + { + eds_ring_write(ringBuffer, scanlines[0], bufSize); + } + + // decode until valida data + if (isBackSide) + { + if (sum >= s->height_back) + { + break; + } + }else + { + if (sum >= s->height_front) + { + break; + } + } + } + DBG(10,"decodded lines = %d\n", sum); + + // abandon unncessary data + if ((JDIMENSION)sum < jpeg_cinfo.output_height) + { + // unncessary data + while(1) + { + int l = jpeg_read_scanlines(&jpeg_cinfo, scanlines, 1); + if (l == 0) + { + break; + } + } } - } else { - DBG(0, "%s: cannot read JPEG header\n", __func__); - return SANE_STATUS_IO_ERROR; - } -} - -void -eds_jpeg_finish(epsonds_scanner *s) -{ - jpeg_destroy_decompress(&s->jpeg_cinfo); -} - -void -eds_jpeg_read(SANE_Handle handle, SANE_Byte *data, - SANE_Int max_length, SANE_Int *length) -{ - epsonds_scanner *s = handle; - - struct jpeg_decompress_struct cinfo = s->jpeg_cinfo; - epsonds_src_mgr *src = (epsonds_src_mgr *)s->jpeg_cinfo.src; - - int l; - - *length = 0; - - /* copy from line buffer if available */ - if (src->linebuffer_size && src->linebuffer_index < src->linebuffer_size) { - - *length = src->linebuffer_size - src->linebuffer_index; - - if (*length > max_length) - *length = max_length; - - memcpy(data, src->linebuffer + src->linebuffer_index, *length); - src->linebuffer_index += *length; - - return; - } - - if (cinfo.output_scanline >= cinfo.output_height) { - *length = 0; - return; - } - - /* scanlines of decompressed data will be in s->jdst->buffer - * only one line at time is supported - */ - - l = jpeg_read_scanlines(&cinfo, s->jdst->buffer, 1); - if (l == 0) { - return; - } - - /* from s->jdst->buffer to linebuffer - * linebuffer holds width * bytesperpixel - */ - - (*s->jdst->put_pixel_rows)(&cinfo, s->jdst, 1, (char *)src->linebuffer); - - *length = cinfo.output_width * cinfo.output_components * 1; - src->linebuffer_size = *length; - src->linebuffer_index = 0; - - if (*length > max_length) - *length = max_length; - memcpy(data, src->linebuffer + src->linebuffer_index, *length); - src->linebuffer_index += *length; + // if not auto crop mode padding to lines + if (s->val[OPT_ADF_CRP].w == 0) + { + unsigned char* padding = malloc(s->params.bytes_per_line); + memset(padding, 255, s->params.bytes_per_line); + DBG(10,"padding data lines = %d to %d pa \n", sum, s->params.lines); + + while(sum < s->params.lines) + { + eds_ring_write(ringBuffer, padding, bufSize); + sum++; + } + + free(padding); + padding = NULL; + } + } + { + jpeg_finish_decompress(&jpeg_cinfo); + jpeg_destroy_decompress(&jpeg_cinfo); + } + return; } |