summaryrefslogtreecommitdiff
path: root/backend/epsonds-jpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'backend/epsonds-jpeg.c')
-rw-r--r--backend/epsonds-jpeg.c311
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;
}