| commit 1e88e1504ef77f09d49da95d393a0af09d20f7fa |
| Author: Ralph Little <skelband@gmail.com> |
| Date: Sat Jul 3 15:55:25 2021 -0700 |
| |
| epsonds: Merge to master |
| |
| diff --git a/backend/Makefile.am b/backend/Makefile.am |
| index 48a1393a5..ca282e4c6 100644 |
| --- a/backend/Makefile.am |
| +++ b/backend/Makefile.am |
| @@ -511,11 +511,20 @@ libepsonds_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=epsonds |
| nodist_libsane_epsonds_la_SOURCES = epsonds-s.c |
| libsane_epsonds_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=epsonds |
| libsane_epsonds_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) |
| + |
| +if have_libavahi |
| +libsane_epsonds_la_LIBADD = $(COMMON_LIBS) libepsonds.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo \ |
| + ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo \ |
| + ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo \ |
| + ../sanei/sanei_tcp.lo ../sanei/sanei_udp.lo \ |
| + $(SANEI_SANEI_JPEG_LO) $(JPEG_LIBS) $(USB_LIBS) $(MATH_LIB) $(RESMGR_LIBS) $(SOCKET_LIBS) $(AVAHI_LIBS) |
| +else |
| libsane_epsonds_la_LIBADD = $(COMMON_LIBS) libepsonds.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo \ |
| ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo \ |
| ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo \ |
| ../sanei/sanei_tcp.lo ../sanei/sanei_udp.lo \ |
| $(SANEI_SANEI_JPEG_LO) $(JPEG_LIBS) $(USB_LIBS) $(MATH_LIB) $(RESMGR_LIBS) $(SOCKET_LIBS) |
| +endif |
| EXTRA_DIST += epsonds.conf.in |
| |
| libfujitsu_la_SOURCES = fujitsu.c fujitsu.h fujitsu-scsi.h |
| diff --git a/backend/epsonds-cmd.c b/backend/epsonds-cmd.c |
| index 5141e0765..6f0ec6487 100644 |
| --- a/backend/epsonds-cmd.c |
| +++ b/backend/epsonds-cmd.c |
| @@ -134,6 +134,7 @@ static SANE_Status esci2_cmd(epsonds_scanner* s, |
| SANE_Status status; |
| unsigned int more; |
| char header[13], rbuf[64]; /* add one more byte for header buffer to correct buffer overflow issue,*/ |
| + char *buf; |
| |
| DBG(8, "%s: %4s len %lu, payload len: %lu\n", __func__, cmd, len, plen); |
| |
| @@ -151,6 +152,21 @@ static SANE_Status esci2_cmd(epsonds_scanner* s, |
| |
| // send RequestBlock, request immediate response if there's no payload |
| status = eds_txrx(s, header, len, rbuf, (plen > 0) ? 0 : 64); |
| + |
| + /* pointer to the token's value */ |
| + buf = rbuf + 12; |
| + /* nrd / nrdBUSY */ |
| + DBG(8, "buf = %s\n",buf); |
| + if (strncmp("#nrd", buf, 4) == 0) { |
| + buf += 4; |
| + DBG(8, "buf = %s\n",buf); |
| + if (strncmp("BUSY", buf, 4) == 0) { |
| + DBG(8, "device busy\n"); |
| + DBG(8, "SANE_STATUS:%d\n", SANE_STATUS_DEVICE_BUSY); |
| + return SANE_STATUS_DEVICE_BUSY; |
| + } |
| + } |
| + |
| if (status != SANE_STATUS_GOOD) { |
| return status; |
| } |
| @@ -227,6 +243,21 @@ SANE_Status esci2_fin(epsonds_scanner *s) |
| DBG(5, "%s\n", __func__); |
| |
| status = esci2_cmd_simple(s, "FIN x0000000", NULL); |
| + |
| + for(int i = 0; i < 10; i++) { |
| + |
| + if(status == SANE_STATUS_DEVICE_BUSY || status == SANE_STATUS_IO_ERROR) { |
| + status = esci2_cmd_simple(s, "FIN x0000000", NULL); |
| + } |
| + else { |
| + DBG(1, "break\n"); |
| + break; |
| + } |
| + DBG(1, "sleep(5)\n"); |
| + sleep(5); |
| + |
| + } |
| + |
| s->locked = 0; |
| return status; |
| } |
| @@ -264,13 +295,13 @@ static char *decode_binary(char *buf, int len) |
| |
| memcpy(tmp, buf, 4); |
| tmp[4] = '\0'; |
| - len -= 4; |
| |
| if (buf[0] != 'h') |
| return NULL; |
| |
| hl = strtol(tmp + 1, NULL, 16); |
| - if (hl > len) hl = len; |
| + if (hl > len) |
| + hl = len; |
| if (hl) { |
| |
| char *v = malloc(hl + 1); |
| @@ -313,9 +344,6 @@ static SANE_Status info_cb(void *userdata, char *token, int len) |
| epsonds_scanner *s = (epsonds_scanner *)userdata; |
| char *value; |
| |
| - if (DBG_LEVEL >= 11) { |
| - debug_token(DBG_LEVEL, __func__, token, len); |
| - } |
| |
| /* pointer to the token's value */ |
| value = token + 3; |
| @@ -333,7 +361,6 @@ static SANE_Status info_cb(void *userdata, char *token, int len) |
| s->hw->model = decode_string(value, len); |
| s->hw->sane.model = s->hw->model; |
| DBG(1, " product: %s\n", s->hw->model); |
| - /* we will free the string later */ |
| } |
| |
| if (strncmp("VER", token, 3) == 0) { |
| @@ -421,6 +448,7 @@ static SANE_Status info_cb(void *userdata, char *token, int len) |
| int max = decode_value(value + 4 + 8, 8); |
| |
| DBG(1, " ADF: area %dx%d @ 100dpi\n", min, max); |
| + eds_set_adf_area(s->hw, min, max, 100); |
| } |
| |
| if (strncmp("AMIN", value, 4) == 0) { |
| @@ -437,11 +465,40 @@ static SANE_Status info_cb(void *userdata, char *token, int len) |
| int max = decode_value(value + 4 + 8, 8); |
| |
| DBG(1, " ADF: max %dx%d @ 100dpi\n", min, max); |
| + } |
| + } |
| + |
| + |
| + |
| + |
| + |
| + |
| + if (len == 16) { |
| + |
| + if (strncmp("AREA", value, 4) == 0) { |
| + |
| + int min = decode_value(value + 4, 4); |
| + int max = decode_value(value + 4 + 4, 8); |
| + |
| + DBG(1, " ADF: area %dx%d @ 100dpi\n", min, max); |
| |
| eds_set_adf_area(s->hw, min, max, 100); |
| } |
| + |
| + if (strncmp("AMAX", value, 4) == 0) { |
| + |
| + // d |
| + int min = decode_value(value + 4, 4); |
| + // i |
| + int max = decode_value(value + 4 + 4, 8); |
| + |
| + DBG(1, " ADF: max %dx%d @ 100dpi\n", min, max); |
| + } |
| } |
| |
| + |
| + |
| + |
| if (len == 12) { |
| |
| /* RESOi0000600 */ |
| @@ -483,6 +540,22 @@ static SANE_Status info_cb(void *userdata, char *token, int len) |
| } |
| } |
| |
| + |
| + if (len == 16) { |
| + |
| + /* AREAi0000850i0001400 */ |
| + if (strncmp("AREA", value, 4) == 0) { |
| + //d |
| + int min = decode_value(value + 4, 4); |
| + //i |
| + int max = decode_value(value + 4 + 4, 8); |
| + |
| + DBG(1, " FB: area %dx%d @ 100dpi\n", min, max); |
| + |
| + eds_set_fbf_area(s->hw, min, max, 100); |
| + } |
| + } |
| + |
| if (len == 8) { |
| |
| if (strncmp("ALGNLEFT", value, len) == 0) { |
| @@ -602,6 +675,7 @@ static SANE_Status capa_cb(void *userdata, char *token, int len) |
| |
| if (strncmp("ADFCRP ", token, 3 + 4) == 0) { |
| DBG(1, " ADF: image cropping\n"); |
| + s->hw->adf_has_crp = 1; |
| } |
| |
| if (strncmp("ADFFAST", token, 3 + 4) == 0) { |
| @@ -636,6 +710,23 @@ static SANE_Status capa_cb(void *userdata, char *token, int len) |
| } |
| } |
| |
| + |
| + if (strncmp("COLLIST", token, 3 + 4) == 0) |
| + { |
| + char *p = token + 3 + 4; |
| + int count = (len - 4); |
| + int readBytes = 0; |
| + s->hw->has_mono = 0; |
| + while (readBytes < count) { |
| + if (strncmp(p, "M001", 4) == 0) |
| + { |
| + s->hw->has_mono = 1; |
| + } |
| + readBytes+=4; |
| + p+=4; |
| + } |
| + } |
| + |
| /* RSMRANGi0000050i0000600 */ |
| |
| if (strncmp("RSMRANG", token, 3 + 4) == 0) { |
| @@ -659,17 +750,24 @@ static SANE_Status capa_cb(void *userdata, char *token, int len) |
| |
| char *p = token + 3 + 4; |
| |
| - if (p[0] == 'i') { |
| |
| - int i; |
| - int count = (len - 4) / 8; |
| - |
| - for (i = 0; i < count; i++) { |
| + int count = (len - 4); |
| + int readBytes = 0; |
| |
| + while (readBytes < count) { |
| + if(*p == 'i') |
| + { |
| eds_add_resolution(s->hw, decode_value(p, 8)); |
| p += 8; |
| + readBytes += 8; |
| + }else if(*p == 'd') |
| + { |
| + eds_add_resolution(s->hw, decode_value(p, 4)); |
| + p += 4; |
| + readBytes +=4; |
| + } |
| } |
| - } |
| + |
| } |
| |
| return SANE_STATUS_GOOD; |
| @@ -684,16 +782,26 @@ SANE_Status esci2_capa(epsonds_scanner *s) |
| |
| static SANE_Status stat_cb(void *userdata, char *token, int len) |
| { |
| -/* |
| - epsonds_scanner *s = (epsonds_scanner *)userdata; |
| char *value = token + 3; |
| -*/ |
| + |
| userdata = userdata; |
| |
| if (DBG_LEVEL >= 11) { |
| debug_token(DBG_LEVEL, __func__, token, len); |
| } |
| |
| + if (strncmp("ERR", token, 3) == 0) { |
| + if (strncmp("ADF PE ", value, len) == 0) { |
| + DBG(1, " PE : paper empty\n"); |
| + return SANE_STATUS_NO_DOCS; |
| + } |
| + |
| + if (strncmp("ADF OPN", value, len) == 0) { |
| + DBG(1, " conver open\n"); |
| + return SANE_STATUS_COVER_OPEN; |
| + } |
| + } |
| + |
| return SANE_STATUS_GOOD; |
| } |
| |
| @@ -742,10 +850,10 @@ static SANE_Status para_cb(void *userdata, char *token, int len) |
| return SANE_STATUS_GOOD; |
| } |
| |
| -SANE_Status esci2_para(epsonds_scanner *s, char *parameters) |
| +SANE_Status esci2_para(epsonds_scanner *s, char *parameters, int len) |
| { |
| DBG(8, "%s: %s\n", __func__, parameters); |
| - return esci2_cmd(s, "PARAx0000000", 12, parameters, strlen(parameters), NULL, ¶_cb); |
| + return esci2_cmd(s, "PARAx0000000", 12, parameters, len, NULL, ¶_cb); |
| } |
| |
| SANE_Status esci2_mech(epsonds_scanner *s, char *parameters) |
| @@ -784,12 +892,105 @@ static SANE_Status img_cb(void *userdata, char *token, int len) |
| return SANE_STATUS_GOOD; |
| } |
| |
| + if (len == 12 && strncmp("pst", token, 3) == 0) { |
| + |
| + s->dummy = decode_value(token + 3 + 4, 4); |
| + |
| + DBG(10, "%s: pst width: %d, height: %d, dummy: %d\n", |
| + __func__, |
| + decode_value(token + 3, 4), |
| + decode_value(token + 3 + 4 + 4, 4), |
| + s->dummy); |
| + |
| + return SANE_STATUS_GOOD; |
| + } |
| + |
| + if (len == 16 && strncmp("pst", token, 3) == 0) { |
| + |
| + s->dummy = decode_value(token + 3 + 4, 4); |
| + |
| + DBG(10, "%s: pst width: %d, height: %d, dummy: %d\n", |
| + __func__, |
| + decode_value(token + 3, 4), |
| + decode_value(token + 3 + 4 + 4, 8), |
| + s->dummy); |
| + |
| + return SANE_STATUS_GOOD; |
| + } |
| + |
| + if (len == 20 && strncmp("pst", token, 3) == 0) { |
| + |
| + s->dummy = decode_value(token + 3 + 8, 4); |
| + |
| + DBG(10, "%s: pst width: %d, height: %d, dummy: %d\n", |
| + __func__, |
| + decode_value(token + 3, 8), |
| + decode_value(token + 3 + 8 + 4, 8), |
| + s->dummy); |
| + |
| + return SANE_STATUS_GOOD; |
| + } |
| + |
| + |
| + // i0001696i0002347 |
| if (len == 16 && strncmp("pen", token, 3) == 0) { |
| DBG(10, "%s: page end\n", __func__); |
| s->eof = 1; |
| + if (s->isflatbedScan) |
| + { |
| + s->scanning = 0; |
| + } |
| + DBG(10, "%s: pen width: %d, height: %d, dummy: %d\n", |
| + __func__, |
| + decode_value(token + 3, 8), |
| + decode_value(token + 3 + 8, 8), |
| + s->dummy); |
| + s->width_temp = decode_value(token + 3, 8); |
| + s->height_temp = decode_value(token + 3 + 8, 8); |
| return SANE_STATUS_EOF; |
| } |
| |
| + // d696i0002347 |
| + if (len == 12 && strncmp("pen", token, 3) == 0) { |
| + DBG(10, "%s: page end\n", __func__); |
| + s->eof = 1; |
| + if (s->isflatbedScan) |
| + { |
| + s->scanning = 0; |
| + } |
| + |
| + DBG(10, "%s: pen width: %d, height: %d, dummy: %d\n", |
| + __func__, |
| + decode_value(token + 3, 4), |
| + decode_value(token + 3 + 4, 8), |
| + s->dummy); |
| + |
| + s->width_temp = decode_value(token + 3, 4); |
| + s->height_temp = decode_value(token + 3 + 4, 8); |
| + return SANE_STATUS_EOF; |
| + } |
| + |
| + // d696d2347 |
| + if (len == 8 && strncmp("pen", token, 3) == 0) { |
| + DBG(10, "%s: page end\n", __func__); |
| + s->eof = 1; |
| + if (s->isflatbedScan) |
| + { |
| + s->scanning = 0; |
| + } |
| + DBG(10, "%s: pen width: %d, height: %d, dummy: %d\n", |
| + __func__, |
| + decode_value(token + 3, 4), |
| + decode_value(token + 3 + 4, 4), |
| + s->dummy); |
| + |
| + s->width_temp = decode_value(token + 3, 4); |
| + s->height_temp = decode_value(token + 3 + 4, 4); |
| + |
| + return SANE_STATUS_EOF; |
| + } |
| + |
| + |
| /* typIMGA or typIMGB */ |
| if (len == 4 && strncmp("typ", token, 3) == 0) { |
| |
| @@ -807,6 +1008,7 @@ static SANE_Status img_cb(void *userdata, char *token, int len) |
| char *cause = token + 3 + 4; /* OPN, PJ, PE, ERR, LTF, LOCK, DFED, DTCL, AUT, PERM */ |
| |
| s->scanning = 0; |
| + s->scanEnd = 1; |
| |
| DBG(1, "%s: error on option %3.3s, cause %4.4s\n", |
| __func__, option, cause); |
| @@ -831,6 +1033,8 @@ static SANE_Status img_cb(void *userdata, char *token, int len) |
| } |
| |
| if (len == 4 && strncmp("lftd000", token, 3 + 4) == 0) { |
| + DBG(1, "%s:lft ok\n", __func__); |
| + s->scanEnd = 1; |
| s->scanning = 0; |
| } |
| |
| @@ -846,6 +1050,8 @@ esci2_img(struct epsonds_scanner *s, SANE_Int *length) |
| unsigned int more; |
| ssize_t read; |
| |
| + DBG(15, "esci2_img start\n"); |
| + |
| *length = 0; |
| |
| if (s->canceling) |
| @@ -856,6 +1062,7 @@ esci2_img(struct epsonds_scanner *s, SANE_Int *length) |
| if (status != SANE_STATUS_GOOD) { |
| return status; |
| } |
| + DBG(15, "request img OK\n"); |
| |
| /* receive DataHeaderBlock */ |
| memset(s->buf, 0x00, 64); |
| @@ -863,6 +1070,7 @@ esci2_img(struct epsonds_scanner *s, SANE_Int *length) |
| if (status != SANE_STATUS_GOOD) { |
| return status; |
| } |
| + DBG(15, "receive img OK\n"); |
| |
| /* check if we need to read any image data */ |
| more = 0; |
| @@ -873,6 +1081,17 @@ esci2_img(struct epsonds_scanner *s, SANE_Int *length) |
| /* this handles eof and errors */ |
| parse_status = esci2_parse_block((char *)s->buf + 12, 64 - 12, s, &img_cb); |
| |
| + if (s->backside) |
| + { |
| + s->width_back = s->width_temp; |
| + s->height_back = s->height_temp; |
| + }else{ |
| + s->width_front = s->width_temp; |
| + s->height_front = s->height_temp; |
| + |
| + } |
| + |
| + |
| /* no more data? return using the status of the esci2_parse_block |
| * call, which might hold other error conditions. |
| */ |
| @@ -884,7 +1103,6 @@ esci2_img(struct epsonds_scanner *s, SANE_Int *length) |
| if (more > s->bsz) { |
| return SANE_STATUS_IO_ERROR; |
| } |
| - |
| /* ALWAYS read image data */ |
| if (s->hw->connection == SANE_EPSONDS_NET) { |
| epsonds_net_request_read(s, more); |
| diff --git a/backend/epsonds-cmd.h b/backend/epsonds-cmd.h |
| index 973609a03..2bd19dbb3 100644 |
| --- a/backend/epsonds-cmd.h |
| +++ b/backend/epsonds-cmd.h |
| @@ -20,7 +20,7 @@ SANE_Status esci2_can(epsonds_scanner *s); |
| SANE_Status esci2_capa(epsonds_scanner *s); |
| SANE_Status esci2_resa(epsonds_scanner *s); |
| SANE_Status esci2_stat(epsonds_scanner *s); |
| -SANE_Status esci2_para(epsonds_scanner *s, char *parameters); |
| +SANE_Status esci2_para(epsonds_scanner *s, char *parameters, int len); |
| SANE_Status esci2_mech(epsonds_scanner *s, char *parameters); |
| SANE_Status esci2_trdt(epsonds_scanner *s); |
| SANE_Status esci2_img(struct epsonds_scanner *s, SANE_Int *length) ; |
| diff --git a/backend/epsonds-jpeg.c b/backend/epsonds-jpeg.c |
| index 244f442ec..99ca53af2 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) |
| + |
| +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; |
| + struct jpeg_decompress_struct jpeg_cinfo; |
| + struct my_error_mgr jpeg_err; |
| |
| - s->jpeg_cinfo.err = jpeg_std_error(&s->jpeg_err); |
| + { |
| + epsonds_src_mgr *src; |
| |
| - jpeg_create_decompress(&s->jpeg_cinfo); |
| + jpeg_cinfo.err = jpeg_custom_error(&jpeg_err); |
| |
| - 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)); |
| + jpeg_create_decompress(&jpeg_cinfo); |
| |
| - memset(s->jpeg_cinfo.src, 0x00, sizeof(epsonds_src_mgr)); |
| + jpeg_cinfo.src = (struct jpeg_source_mgr *)(*jpeg_cinfo.mem->alloc_small)((j_common_ptr)&jpeg_cinfo, |
| + JPOOL_PERMANENT, sizeof(epsonds_src_mgr)); |
| |
| - src = (epsonds_src_mgr *)s->jpeg_cinfo.src; |
| - src->s = s; |
| + 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)) { |
| |
| - src->buffer = (JOCTET *)(*s->jpeg_cinfo.mem->alloc_small)((j_common_ptr)&s->jpeg_cinfo, |
| - JPOOL_PERMANENT, |
| - 1024 * sizeof(JOCTET)); |
| + if (jpeg_start_decompress(&jpeg_cinfo)) { |
| |
| - 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) |
| -{ |
| - 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", |
| + 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); |
| } |
| - } 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; |
| + } |
| + } |
| + { |
| + 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; |
| + } |
| + } |
| + } |
| + |
| + // 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; |
| } |
| diff --git a/backend/epsonds-jpeg.h b/backend/epsonds-jpeg.h |
| index a804dec9b..42f542d33 100644 |
| --- a/backend/epsonds-jpeg.h |
| +++ b/backend/epsonds-jpeg.h |
| @@ -10,8 +10,4 @@ |
| * modify it under the terms of the GNU General Public License as |
| * published by the Free Software Foundation, version 2. |
| */ |
| - |
| -SANE_Status eds_jpeg_start(epsonds_scanner *s); |
| -void eds_jpeg_finish(epsonds_scanner *s); |
| -SANE_Status eds_jpeg_read_header(epsonds_scanner *s); |
| -void eds_jpeg_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length, SANE_Int *length); |
| +void eds_decode_jpeg(epsonds_scanner*s, SANE_Byte *data, SANE_Int size, ring_buffer* ringBuffer, SANE_Int isBackSide, SANE_Int needToConvertBW); |
| diff --git a/backend/epsonds-net.c b/backend/epsonds-net.c |
| index 3c8be2931..4f4c1e267 100644 |
| --- a/backend/epsonds-net.c |
| +++ b/backend/epsonds-net.c |
| @@ -32,10 +32,19 @@ |
| |
| #include "sane/sanei_debug.h" |
| |
| + |
| static ssize_t |
| epsonds_net_read_raw(epsonds_scanner *s, unsigned char *buf, ssize_t wanted, |
| SANE_Status *status) |
| { |
| + DBG(15, "%s: wanted: %ld\n", __func__, wanted); |
| + |
| + if (wanted == 0) |
| + { |
| + *status = SANE_STATUS_GOOD; |
| + return 0; |
| + } |
| + |
| int ready; |
| ssize_t read = -1; |
| fd_set readable; |
| @@ -284,3 +293,228 @@ epsonds_net_unlock(struct epsonds_scanner *s) |
| /* epsonds_net_read(s, buf, 1, &status); */ |
| return status; |
| } |
| +#if WITH_AVAHI |
| + |
| +#include <assert.h> |
| +#include <stdio.h> |
| +#include <stdlib.h> |
| +#include <string.h> |
| +#include <avahi-client/lookup.h> |
| +#include <avahi-common/error.h> |
| +#include <avahi-common/simple-watch.h> |
| +#include <sys/time.h> |
| +#include <errno.h> |
| + |
| +static AvahiSimplePoll *simple_poll = NULL; |
| + |
| +static struct timeval borowseEndTime; |
| + |
| +static int resolvedCount = 0; |
| +static int browsedCount = 0; |
| +static int waitResolver = 0; |
| + |
| +typedef struct { |
| + AvahiClient* client; |
| + Device_Found_CallBack callBack; |
| +}EDSAvahiUserData; |
| + |
| +static int my_avahi_simple_poll_loop(AvahiSimplePoll *s) { |
| + struct timeval currentTime; |
| + |
| + for (;;) |
| + { |
| + int r = avahi_simple_poll_iterate(s, 1); |
| + if (r != 0) |
| + { |
| + if (r >= 0 || errno != EINTR) |
| + { |
| + DBG(10, "my_avahi_simple_poll_loop end\n"); |
| + return r; |
| + } |
| + } |
| + |
| + if (waitResolver) { |
| + gettimeofday(¤tTime, NULL); |
| + |
| + if ((currentTime.tv_sec - borowseEndTime.tv_sec) >= 3) |
| + { |
| + avahi_simple_poll_quit(simple_poll); |
| + DBG(10, "resolve timeout\n"); |
| + return 0; |
| + } |
| + } |
| + } |
| +} |
| + |
| +static void |
| +epsonds_resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interface, |
| + AVAHI_GCC_UNUSED AvahiProtocol protocol, |
| + AvahiResolverEvent event, const char *name, |
| + const char *type, |
| + const char *domain, |
| + const char *host_name, |
| + const AvahiAddress *address, uint16_t port, AvahiStringList *txt, |
| + AvahiLookupResultFlags flags, |
| + void *userdata) |
| +{ |
| + // unused parameter |
| + (void)r; |
| + (void)type; |
| + (void)domain; |
| + (void)host_name; |
| + (void)port; |
| + (void)flags; |
| + EDSAvahiUserData* data = userdata; |
| + char ipAddr[AVAHI_ADDRESS_STR_MAX]; |
| + |
| + DBG(10, "epsonds_searchDevices resolve_callback\n"); |
| + |
| + |
| + resolvedCount++; |
| + |
| + switch (event) { |
| + case AVAHI_RESOLVER_FAILURE: |
| + break; |
| + case AVAHI_RESOLVER_FOUND: |
| + avahi_address_snprint(ipAddr, sizeof(ipAddr), address); |
| + DBG(10, "epsonds_searchDevices name = %s \n", name); |
| + if (strlen(name) > 7) |
| + { |
| + if (strncmp(name, "EPSON", 5) == 0) |
| + { |
| + while(txt != NULL) |
| + { |
| + char* text = (char*)avahi_string_list_get_text(txt); |
| + DBG(10, "avahi string = %s\n", text); |
| + |
| + if (strlen(text) > 4 && strncmp(text, "mdl=", 4) == 0) |
| + { |
| + if (data->callBack) |
| + { |
| + data->callBack(&text[4], ipAddr); |
| + break; |
| + } |
| + } |
| + txt = avahi_string_list_get_next(txt); |
| + } |
| + |
| + } |
| + } |
| + break; |
| + } |
| +} |
| + |
| +static void |
| +browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, |
| + AvahiProtocol protocol, AvahiBrowserEvent event, |
| + const char *name, const char *type, |
| + const char *domain, |
| + AvahiLookupResultFlags flags, |
| + void* userdata) |
| +{ |
| + DBG(10, "browse_callback event = %d\n", event); |
| + |
| + //unused parameter |
| + (void)b; |
| + (void)flags; |
| + |
| + EDSAvahiUserData *data = userdata; |
| + switch (event) { |
| + case AVAHI_BROWSER_FAILURE: |
| + avahi_simple_poll_quit(simple_poll); |
| + return; |
| + case AVAHI_BROWSER_NEW: |
| + DBG(10, "browse_callback name = %s\n", name); |
| + browsedCount++; |
| + if (!(avahi_service_resolver_new(data->client, interface, protocol, name, |
| + type, domain, |
| + AVAHI_PROTO_UNSPEC, 0, |
| + epsonds_resolve_callback, data))) |
| + { |
| + DBG(10, "avahi_service_resolver_new fails\n"); |
| + break; |
| + } |
| + case AVAHI_BROWSER_REMOVE: |
| + break; |
| + case AVAHI_BROWSER_ALL_FOR_NOW: |
| + DBG(10, "AVAHI_BROWSER_ALL_FOR_NOW\n"); |
| + gettimeofday(&borowseEndTime, NULL); |
| + |
| + if (browsedCount > resolvedCount) |
| + { |
| + DBG(10, "WAIT RESOLVER\n"); |
| + waitResolver = 1; |
| + }else{ |
| + DBG(10, "QUIT POLL\n"); |
| + avahi_simple_poll_quit(simple_poll); |
| + } |
| + break; |
| + case AVAHI_BROWSER_CACHE_EXHAUSTED: |
| + DBG(10, "AVAHI_BROWSER_CACHE_EXHAUSTED\n"); |
| + break; |
| + } |
| +} |
| + |
| +static void |
| +client_callback(AvahiClient *c, AvahiClientState state, |
| + AVAHI_GCC_UNUSED void *userdata) |
| +{ |
| + assert(c); |
| + if (state == AVAHI_CLIENT_FAILURE) |
| + avahi_simple_poll_quit(simple_poll); |
| +} |
| + |
| +SANE_Status epsonds_searchDevices(Device_Found_CallBack deviceFoundCallBack) |
| +{ |
| + int result = SANE_STATUS_GOOD; |
| + |
| + AvahiClient *client = NULL; |
| + AvahiServiceBrowser *sb = NULL; |
| + |
| + EDSAvahiUserData data; |
| + |
| + resolvedCount = 0; |
| + browsedCount = 0; |
| + waitResolver = 0; |
| + |
| + |
| + int error = 0; |
| + DBG(10, "epsonds_searchDevices\n"); |
| + |
| + if (!(simple_poll = avahi_simple_poll_new())) { |
| + DBG(10, "avahi_simple_poll_new failed\n"); |
| + result = SANE_STATUS_INVAL; |
| + goto fail; |
| + } |
| + client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, |
| + client_callback, NULL, &error); |
| + if (!client) { |
| + DBG(10, "avahi_client_new failed %s\n", avahi_strerror(error)); |
| + result = SANE_STATUS_INVAL; |
| + goto fail; |
| + } |
| + data.client = client; |
| + data.callBack = deviceFoundCallBack; |
| + |
| + if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, |
| + AVAHI_PROTO_UNSPEC, "_scanner._tcp", |
| + NULL, 0, browse_callback, &data))) { |
| + DBG(10, "avahi_service_browser_new failed: %s\n", |
| + avahi_strerror(avahi_client_errno(client))); |
| + result = SANE_STATUS_INVAL; |
| + goto fail; |
| + } |
| + my_avahi_simple_poll_loop(simple_poll); |
| +fail: |
| + if (sb) |
| + avahi_service_browser_free(sb); |
| + if (client) |
| + avahi_client_free(client); |
| + if (simple_poll) |
| + avahi_simple_poll_free(simple_poll); |
| + |
| + DBG(10, "epsonds_searchDevices fin\n"); |
| + |
| + return result; |
| +} |
| +#endif |
| diff --git a/backend/epsonds-net.h b/backend/epsonds-net.h |
| index 107301bdc..2431c3594 100644 |
| --- a/backend/epsonds-net.h |
| +++ b/backend/epsonds-net.h |
| @@ -4,6 +4,8 @@ |
| #include <sys/types.h> |
| #include "../include/sane/sane.h" |
| |
| +typedef void (*Device_Found_CallBack) (const char* name, const char* ip); |
| + |
| extern ssize_t epsonds_net_read(struct epsonds_scanner *s, unsigned char *buf, ssize_t buf_size, |
| SANE_Status *status); |
| extern size_t epsonds_net_write(struct epsonds_scanner *s, unsigned int cmd, const unsigned char *buf, |
| @@ -13,4 +15,8 @@ extern SANE_Status epsonds_net_lock(struct epsonds_scanner *s); |
| extern SANE_Status epsonds_net_unlock(struct epsonds_scanner *s); |
| extern SANE_Status epsonds_net_request_read(epsonds_scanner *s, size_t len); |
| |
| +#if WITH_AVAHI |
| +extern SANE_Status epsonds_searchDevices(Device_Found_CallBack deviceFoundCallBack); |
| +#endif |
| + |
| #endif |
| diff --git a/backend/epsonds-ops.c b/backend/epsonds-ops.c |
| index 8b9d11586..56194c428 100644 |
| --- a/backend/epsonds-ops.c |
| +++ b/backend/epsonds-ops.c |
| @@ -28,10 +28,9 @@ |
| extern struct mode_param mode_params[]; |
| |
| /* Define the different scan sources */ |
| - |
| -#define FBF_STR SANE_I18N("Flatbed") |
| -#define TPU_STR SANE_I18N("Transparency Unit") |
| -#define ADF_STR SANE_I18N("Automatic Document Feeder") |
| +#define STRING_FLATBED SANE_I18N("Flatbed") |
| +#define STRING_ADFFRONT SANE_I18N("ADF Front") |
| +#define STRING_ADFDUPLEX SANE_I18N("ADF Duplex") |
| |
| extern SANE_String_Const source_list[]; |
| |
| @@ -53,10 +52,13 @@ eds_dev_post_init(struct epsonds_device *dev) |
| DBG(10, "%s\n", __func__); |
| |
| if (dev->has_fb) |
| - *source_list_add++ = FBF_STR; |
| + *source_list_add++ = STRING_FLATBED; |
| |
| if (dev->has_adf) |
| - *source_list_add++ = ADF_STR; |
| + *source_list_add++ = STRING_ADFFRONT; |
| + |
| + if (dev->adf_is_duplex) |
| + *source_list_add++ = STRING_ADFDUPLEX; |
| |
| if (source_list[0] == 0 |
| || (dev->res_list[0] == 0 && dev->dpi_range.min == 0) |
| @@ -209,8 +211,6 @@ eds_init_parameters(epsonds_scanner *s) |
| |
| memset(&s->params, 0, sizeof(SANE_Parameters)); |
| |
| - s->dummy = 0; |
| - |
| /* setup depth according to our mode table */ |
| if (mode_params[s->val[OPT_MODE].w].depth == 1) |
| s->params.depth = 1; |
| @@ -314,6 +314,7 @@ eds_init_parameters(epsonds_scanner *s) |
| |
| return SANE_STATUS_GOOD; |
| } |
| +#define min(A,B) (((A)<(B)) ? (A) : (B)) |
| |
| void |
| eds_copy_image_from_ring(epsonds_scanner *s, SANE_Byte *data, SANE_Int max_length, |
| @@ -322,17 +323,13 @@ eds_copy_image_from_ring(epsonds_scanner *s, SANE_Byte *data, SANE_Int max_lengt |
| int lines, available; |
| int hw_line_size = (s->params.bytes_per_line + s->dummy); |
| |
| - /* trim max_length to a multiple of hw_line_size */ |
| - max_length -= (max_length % hw_line_size); |
| - |
| - /* check available data */ |
| available = eds_ring_avail(s->current); |
| if (max_length > available) |
| max_length = available; |
| |
| - lines = max_length / hw_line_size; |
| + lines = min(max_length / s->params.bytes_per_line, available / hw_line_size); |
| |
| - DBG(18, "copying %d lines (%d, %d)\n", lines, s->params.bytes_per_line, s->dummy); |
| + DBG(18, "copying %d lines (%d, %d, %d)\n", lines, s->params.bytes_per_line, s->dummy, s->params.depth); |
| |
| /* need more data? */ |
| if (lines == 0) { |
| @@ -490,3 +487,12 @@ void eds_ring_flush(ring_buffer *ring) |
| { |
| eds_ring_skip(ring, ring->fill); |
| } |
| + |
| +void eds_ring_destory(ring_buffer *ring) |
| +{ |
| + if (ring->ring) |
| + { |
| + free(ring->ring); |
| + ring->ring = NULL; |
| + } |
| +} |
| diff --git a/backend/epsonds-ops.h b/backend/epsonds-ops.h |
| index fe503d60d..108d5444b 100644 |
| --- a/backend/epsonds-ops.h |
| +++ b/backend/epsonds-ops.h |
| @@ -38,3 +38,4 @@ extern SANE_Int eds_ring_read(ring_buffer *ring, SANE_Byte *buf, SANE_Int size); |
| extern SANE_Int eds_ring_skip(ring_buffer *ring, SANE_Int size); |
| extern SANE_Int eds_ring_avail(ring_buffer *ring); |
| extern void eds_ring_flush(ring_buffer *ring) ; |
| +extern void eds_ring_destory(ring_buffer *ring) ; |
| diff --git a/backend/epsonds-usb.c b/backend/epsonds-usb.c |
| index c7e514cb7..dacfd5fa1 100644 |
| --- a/backend/epsonds-usb.c |
| +++ b/backend/epsonds-usb.c |
| @@ -12,22 +12,3 @@ |
| */ |
| |
| #include "epsonds-usb.h" |
| - |
| -SANE_Word epsonds_usb_product_ids[] = { |
| - 0x0145, /* DS-5500, DS-6500, DS-7500 */ |
| - 0x0146, /* DS-50000, DS-60000, DS-70000 */ |
| - 0x014c, /* DS-510 */ |
| - 0x014d, /* DS-560 */ |
| - 0x0150, /* DS-40 */ |
| - 0x0152, /* DS-760, DS-860 */ |
| - 0x0154, /* DS-520 */ |
| - 0x08bc, /* PX-M7050 Series, WF-8510/8590 Series */ |
| - 0x08cc, /* PX-M7050FX Series, WF-R8590 Series */ |
| - 0 /* last entry - this is used for devices that are specified |
| - in the config file as "usb <vendor> <product>" */ |
| -}; |
| - |
| -int epsonds_get_number_of_ids(void) |
| -{ |
| - return sizeof (epsonds_usb_product_ids) / sizeof (SANE_Word); |
| -} |
| diff --git a/backend/epsonds-usb.h b/backend/epsonds-usb.h |
| index 96c77b5b6..9baab701e 100644 |
| --- a/backend/epsonds-usb.h |
| +++ b/backend/epsonds-usb.h |
| @@ -18,7 +18,4 @@ |
| |
| #define SANE_EPSONDS_VENDOR_ID (0x4b8) |
| |
| -extern SANE_Word epsonds_usb_product_ids[]; |
| -extern int epsonds_get_number_of_ids(void); |
| - |
| #endif |
| diff --git a/backend/epsonds.c b/backend/epsonds.c |
| index 1a7f953d0..06721c3d0 100644 |
| --- a/backend/epsonds.c |
| +++ b/backend/epsonds.c |
| @@ -50,6 +50,7 @@ |
| #include <sys/types.h> |
| #include <sys/socket.h> |
| #include <unistd.h> |
| +#include <math.h> |
| |
| #include "sane/saneopts.h" |
| #include "sane/sanei_config.h" |
| @@ -64,7 +65,8 @@ |
| #include "epsonds-jpeg.h" |
| #include "epsonds-net.h" |
| |
| - |
| +static SANE_Status |
| +setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info); |
| /* |
| * Definition of the mode_param struct, that is used to |
| * specify the valid parameters for the different scan modes. |
| @@ -72,6 +74,1231 @@ |
| * The depth variable gets updated when the bit depth is modified. |
| */ |
| |
| + |
| +static unsigned char LUT[][256] = |
| +{ |
| + {// 0 |
| + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, |
| + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, |
| + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, |
| + 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, |
| + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, |
| + 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, |
| + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, |
| + 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, |
| + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, |
| + 0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, |
| + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, |
| + 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, |
| + 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67, |
| + 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, |
| + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77, |
| + 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F, |
| + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, |
| + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, |
| + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97, |
| + 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, |
| + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7, |
| + 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, |
| + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7, |
| + 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, |
| + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7, |
| + 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, |
| + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7, |
| + 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, |
| + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7, |
| + 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, |
| + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7, |
| + 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF |
| + }, |
| + { // 1 |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| + 0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D, |
| + 0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20, |
| + 0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30, |
| + 0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E, |
| + 0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B, |
| + 0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58, |
| + 0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64, |
| + 0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70, |
| + 0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B, |
| + 0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86, |
| + 0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91, |
| + 0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C, |
| + 0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6, |
| + 0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0, |
| + 0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA, |
| + 0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4, |
| + 0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD, |
| + 0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7, |
| + 0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0, |
| + 0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9, |
| + 0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3, |
| + 0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC, |
| + 0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF |
| + }, |
| + { // 2 |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| + 0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C, |
| + 0x0E,0x10,0x12,0x14,0x16,0x16,0x19,0x1B, |
| + 0x1D,0x1F,0x21,0x23,0x25,0x27,0x28,0x2A, |
| + 0x2C,0x2E,0x30,0x32,0x33,0x35,0x37,0x39, |
| + 0x3A,0x3C,0x3E,0x40,0x41,0x43,0x45,0x46, |
| + 0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53, |
| + 0x55,0x57,0x58,0x5A,0x5B,0x5D,0x5F,0x60, |
| + 0x62,0x63,0x65,0x66,0x68,0x69,0x6B,0x6C, |
| + 0x6E,0x6F,0x71,0x72,0x74,0x75,0x77,0x78, |
| + 0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84, |
| + 0x86,0x87,0x88,0x8A,0x8B,0x8D,0x8E,0x90, |
| + 0x91,0x92,0x94,0x95,0x97,0x98,0x99,0x9B, |
| + 0x9C,0x9E,0x9F,0xA0,0xA2,0xA3,0xA5,0xA7, |
| + 0xA9,0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2, |
| + 0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD, |
| + 0xBE,0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8, |
| + 0xC9,0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2, |
| + 0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD, |
| + 0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7, |
| + 0xE8,0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1, |
| + 0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB, |
| + 0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { // 3 |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x07, |
| + 0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16, |
| + 0x18,0x1A,0x1C,0x1E,0x20,0x22,0x24,0x26, |
| + 0x28,0x2A,0x2B,0x2D,0x2F,0x31,0x33,0x34, |
| + 0x36,0x38,0x39,0x3B,0x3D,0x3E,0x40,0x42, |
| + 0x43,0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4F, |
| + 0x50,0x52,0x53,0x55,0x56,0x58,0x59,0x5B, |
| + 0x5D,0x5E,0x60,0x61,0x63,0x64,0x66,0x67, |
| + 0x69,0x6A,0x6B,0x6D,0x6E,0x70,0x71,0x73, |
| + 0x74,0x76,0x77,0x79,0x7A,0x7B,0x7D,0x7E, |
| + 0x80,0x81,0x83,0x84,0x85,0x87,0x88,0x8A, |
| + 0x8B,0x8C,0x8E,0x8F,0x90,0x92,0x93,0x95, |
| + 0x96,0x97,0x99,0x9A,0x9B,0x9D,0x9E,0x9F, |
| + 0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,0xAA, |
| + 0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,0xB5, |
| + 0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF, |
| + 0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,0xC9, |
| + 0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,0xD4, |
| + 0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,0xDF, |
| + 0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,0xE8,0xE9, |
| + 0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3, |
| + 0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { //4 |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03, |
| + 0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10, |
| + 0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20, |
| + 0x22,0x24,0x26,0x28,0x2A,0x2B,0x2D,0x2F, |
| + 0x31,0x33,0x34,0x36,0x38,0x39,0x3B,0x3D, |
| + 0x3E,0x40,0x42,0x43,0x45,0x47,0x48,0x4A, |
| + 0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,0x56, |
| + 0x58,0x59,0x5B,0x5D,0x5E,0x60,0x61,0x63, |
| + 0x64,0x66,0x67,0x69,0x6A,0x6B,0x6D,0x6E, |
| + 0x70,0x71,0x73,0x74,0x76,0x77,0x79,0x7A, |
| + 0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,0x85, |
| + 0x87,0x88,0x8A,0x8B,0x8C,0x8E,0x8F,0x90, |
| + 0x92,0x93,0x95,0x96,0x97,0x99,0x9A,0x9B, |
| + 0x9D,0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,0xA6, |
| + 0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB1, |
| + 0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB, |
| + 0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC6, |
| + 0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,0xD0, |
| + 0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,0xDA, |
| + 0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,0xE5, |
| + 0xE6,0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF, |
| + 0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9, |
| + 0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { // 5 |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x01,0x02,0x03,0x04,0x05,0x07,0x08,0x0A, |
| + 0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A, |
| + 0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A, |
| + 0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38, |
| + 0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45, |
| + 0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52, |
| + 0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E, |
| + 0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A, |
| + 0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76, |
| + 0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81, |
| + 0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C, |
| + 0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97, |
| + 0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA2, |
| + 0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD, |
| + 0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7, |
| + 0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2, |
| + 0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC, |
| + 0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6, |
| + 0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0, |
| + 0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB, |
| + 0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5, |
| + 0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { // 6 |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, |
| + 0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E, |
| + 0x10,0x12,0x14,0x16,0x18,0x18,0x1A,0x1C, |
| + 0x1E,0x20,0x22,0x24,0x26,0x27,0x29,0x2B, |
| + 0x2C,0x2E,0x30,0x31,0x33,0x35,0x36,0x38, |
| + 0x39,0x3B,0x3C,0x3E,0x40,0x41,0x43,0x44, |
| + 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50, |
| + 0x51,0x52,0x54,0x55,0x56,0x58,0x59,0x5B, |
| + 0x5C,0x5D,0x5F,0x60,0x61,0x63,0x64,0x65, |
| + 0x67,0x68,0x69,0x6A,0x6C,0x6D,0x6E,0x70, |
| + 0x71,0x72,0x73,0x75,0x76,0x77,0x78,0x7A, |
| + 0x7B,0x7C,0x7D,0x7E,0x80,0x81,0x82,0x83, |
| + 0x85,0x86,0x87,0x88,0x89,0x8A,0x8C,0x8D, |
| + 0x8E,0x8F,0x90,0x92,0x93,0x94,0x95,0x96, |
| + 0x97,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, |
| + 0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8, |
| + 0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1, |
| + 0xB2,0xB3,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA, |
| + 0xBB,0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC4, |
| + 0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC, |
| + 0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5, |
| + 0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD, |
| + 0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5, |
| + 0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED, |
| + 0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5, |
| + 0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { // 7 |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, |
| + 0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C, |
| + 0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C, |
| + 0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A, |
| + 0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37, |
| + 0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44, |
| + 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50, |
| + 0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C, |
| + 0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67, |
| + 0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72, |
| + 0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D, |
| + 0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88, |
| + 0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92, |
| + 0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C, |
| + 0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6, |
| + 0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0, |
| + 0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA, |
| + 0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4, |
| + 0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE, |
| + 0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7, |
| + 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1, |
| + 0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA, |
| + 0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3, |
| + 0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + } |
| +}; |
| + |
| +static unsigned char LUT_R[][256] = |
| +{ |
| + { // 0 |
| + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, |
| + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, |
| + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, |
| + 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, |
| + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, |
| + 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, |
| + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, |
| + 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, |
| + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, |
| + 0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, |
| + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, |
| + 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, |
| + 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67, |
| + 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, |
| + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77, |
| + 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F, |
| + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, |
| + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, |
| + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97, |
| + 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, |
| + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7, |
| + 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, |
| + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7, |
| + 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, |
| + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7, |
| + 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, |
| + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7, |
| + 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, |
| + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7, |
| + 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, |
| + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7, |
| + 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF |
| + }, |
| + { // 1 |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| + 0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D, |
| + 0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20, |
| + 0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30, |
| + 0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E, |
| + 0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B, |
| + 0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58, |
| + 0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64, |
| + 0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70, |
| + 0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B, |
| + 0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86, |
| + 0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91, |
| + 0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C, |
| + 0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6, |
| + 0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0, |
| + 0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA, |
| + 0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4, |
| + 0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD, |
| + 0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7, |
| + 0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0, |
| + 0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9, |
| + 0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3, |
| + 0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC, |
| + 0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF |
| + }, |
| + { // 2 |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, |
| + 0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E, |
| + 0x10,0x12,0x14,0x16,0x19,0x1B,0x1D,0x1F, |
| + 0x21,0x23,0x25,0x27,0x28,0x2A,0x2C,0x2E, |
| + 0x30,0x32,0x33,0x35,0x37,0x39,0x3A,0x3C, |
| + 0x3E,0x40,0x41,0x43,0x45,0x46,0x48,0x4A, |
| + 0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,0x57, |
| + 0x58,0x5A,0x5B,0x5D,0x5F,0x60,0x62,0x63, |
| + 0x65,0x66,0x68,0x69,0x6B,0x6C,0x6E,0x6F, |
| + 0x71,0x72,0x74,0x75,0x77,0x78,0x7A,0x7B, |
| + 0x7D,0x7E,0x80,0x81,0x83,0x84,0x86,0x87, |
| + 0x88,0x8A,0x8B,0x8D,0x8E,0x90,0x91,0x92, |
| + 0x94,0x95,0x97,0x98,0x99,0x9B,0x9C,0x9E, |
| + 0x9F,0xA0,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9, |
| + 0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2,0xB4, |
| + 0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD,0xBE, |
| + 0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8,0xC9, |
| + 0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2,0xD4, |
| + 0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD,0xDE, |
| + 0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8, |
| + 0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,0xF2, |
| + 0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,0xFC, |
| + 0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x01,0x02,0x03,0x04,0x05,0x07,0x08,0x0A, |
| + 0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A, |
| + 0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A, |
| + 0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38, |
| + 0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45, |
| + 0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52, |
| + 0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E, |
| + 0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A, |
| + 0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76, |
| + 0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81, |
| + 0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C, |
| + 0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97, |
| + 0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA2, |
| + 0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD, |
| + 0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7, |
| + 0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2, |
| + 0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC, |
| + 0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6, |
| + 0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0, |
| + 0xE1,0xE3,0xE4,0xE5,0xE5,0xE6,0xE8,0xE9, |
| + 0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3, |
| + 0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05, |
| + 0x07,0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14, |
| + 0x16,0x18,0x1A,0x1C,0x1E,0x20,0x22,0x24, |
| + 0x26,0x28,0x2A,0x2B,0x2D,0x2F,0x31,0x33, |
| + 0x34,0x36,0x38,0x39,0x3B,0x3D,0x3E,0x40, |
| + 0x42,0x43,0x45,0x47,0x48,0x4A,0x4B,0x4D, |
| + 0x4F,0x50,0x52,0x53,0x55,0x56,0x58,0x59, |
| + 0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64,0x66, |
| + 0x67,0x69,0x6A,0x6B,0x6D,0x6E,0x70,0x71, |
| + 0x73,0x74,0x76,0x77,0x79,0x7A,0x7B,0x7D, |
| + 0x7E,0x80,0x81,0x83,0x84,0x85,0x87,0x88, |
| + 0x8A,0x8B,0x8C,0x8E,0x8F,0x90,0x92,0x93, |
| + 0x95,0x96,0x97,0x99,0x9A,0x9B,0x9D,0x9E, |
| + 0x9F,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9, |
| + 0xAA,0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,0xB3, |
| + 0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,0xBE, |
| + 0xBF,0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,0xC8, |
| + 0xC9,0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,0xD2, |
| + 0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDC, |
| + 0xDE,0xDF,0xE0,0xE1,0xE3,0xE4,0xE5,0xE6, |
| + 0xE8,0xE9,0xEA,0xEB,0xEB,0xED,0xEE,0xEF, |
| + 0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9, |
| + 0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, |
| + 0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E, |
| + 0x10,0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E, |
| + 0x20,0x22,0x24,0x26,0x28,0x2A,0x2B,0x2D, |
| + 0x2F,0x31,0x33,0x34,0x36,0x38,0x39,0x3B, |
| + 0x3D,0x3E,0x40,0x42,0x43,0x45,0x47,0x48, |
| + 0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55, |
| + 0x56,0x58,0x59,0x5B,0x5D,0x5E,0x60,0x61, |
| + 0x63,0x64,0x66,0x67,0x69,0x6A,0x6B,0x6D, |
| + 0x6E,0x70,0x71,0x73,0x74,0x76,0x77,0x79, |
| + 0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84, |
| + 0x85,0x87,0x88,0x8A,0x8B,0x8C,0x8E,0x8F, |
| + 0x90,0x92,0x93,0x95,0x96,0x97,0x99,0x9A, |
| + 0x9B,0x9D,0x9E,0x9F,0xA1,0xA2,0xA3,0xA5, |
| + 0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF, |
| + 0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,0xBA, |
| + 0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4, |
| + 0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,0xCF, |
| + 0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,0xD9, |
| + 0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,0xE3, |
| + 0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB,0xED, |
| + 0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5,0xF6, |
| + 0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| + 0x02,0x03,0x04,0x05,0x06,0x08,0x0A,0x0C, |
| + 0x0E,0x10,0x12,0x14,0x16,0x19,0x1B,0x1D, |
| + 0x1F,0x20,0x22,0x24,0x26,0x28,0x2A,0x2B, |
| + 0x2D,0x2F,0x31,0x32,0x34,0x35,0x37,0x39, |
| + 0x3A,0x3C,0x3D,0x3F,0x41,0x42,0x44,0x45, |
| + 0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x4F,0x51, |
| + 0x52,0x54,0x55,0x57,0x58,0x59,0x5B,0x5C, |
| + 0x5E,0x5F,0x60,0x62,0x63,0x64,0x66,0x67, |
| + 0x68,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x72, |
| + 0x73,0x74,0x75,0x77,0x78,0x79,0x7B,0x7C, |
| + 0x7D,0x7E,0x80,0x81,0x82,0x83,0x85,0x86, |
| + 0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E,0x90, |
| + 0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99, |
| + 0x9A,0x9B,0x9D,0x9E,0x9F,0xA0,0xA1,0xA2, |
| + 0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAB,0xAC, |
| + 0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB4,0xB5, |
| + 0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBD,0xBE, |
| + 0xBF,0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6, |
| + 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, |
| + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD6,0xD7,0xD8, |
| + 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0, |
| + 0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xEA, |
| + 0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2, |
| + 0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA, |
| + 0xFB,0xFC,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, |
| + 0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C, |
| + 0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C, |
| + 0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A, |
| + 0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37, |
| + 0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44, |
| + 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50, |
| + 0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C, |
| + 0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67, |
| + 0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72, |
| + 0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D, |
| + 0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88, |
| + 0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92, |
| + 0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C, |
| + 0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6, |
| + 0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0, |
| + 0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA, |
| + 0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4, |
| + 0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE, |
| + 0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7, |
| + 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1, |
| + 0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA, |
| + 0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3, |
| + 0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF |
| + } |
| +}; |
| + |
| +static unsigned char LUT_G[][256] = |
| +{ |
| + { |
| + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, |
| + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, |
| + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, |
| + 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, |
| + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, |
| + 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, |
| + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, |
| + 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, |
| + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, |
| + 0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, |
| + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, |
| + 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, |
| + 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67, |
| + 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, |
| + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77, |
| + 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F, |
| + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, |
| + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, |
| + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97, |
| + 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, |
| + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7, |
| + 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, |
| + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7, |
| + 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, |
| + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7, |
| + 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, |
| + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7, |
| + 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, |
| + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7, |
| + 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, |
| + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7, |
| + 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| + 0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D, |
| + 0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20, |
| + 0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30, |
| + 0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E, |
| + 0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B, |
| + 0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58, |
| + 0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64, |
| + 0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70, |
| + 0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B, |
| + 0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86, |
| + 0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91, |
| + 0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C, |
| + 0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6, |
| + 0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0, |
| + 0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA, |
| + 0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4, |
| + 0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD, |
| + 0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7, |
| + 0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0, |
| + 0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9, |
| + 0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3, |
| + 0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC, |
| + 0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| + 0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C, |
| + 0x0E,0x10,0x12,0x14,0x16,0x16,0x19,0x1B, |
| + 0x1D,0x1F,0x21,0x23,0x25,0x27,0x28,0x2A, |
| + 0x2C,0x2E,0x30,0x32,0x33,0x35,0x37,0x39, |
| + 0x3A,0x3C,0x3E,0x40,0x41,0x43,0x45,0x46, |
| + 0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53, |
| + 0x55,0x57,0x58,0x5A,0x5B,0x5D,0x5F,0x60, |
| + 0x62,0x63,0x65,0x66,0x68,0x69,0x6B,0x6C, |
| + 0x6E,0x6F,0x71,0x72,0x74,0x75,0x77,0x78, |
| + 0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84, |
| + 0x86,0x87,0x88,0x8A,0x8B,0x8D,0x8E,0x90, |
| + 0x91,0x92,0x94,0x95,0x97,0x98,0x99,0x9B, |
| + 0x9C,0x9E,0x9F,0xA0,0xA2,0xA3,0xA5,0xA7, |
| + 0xA9,0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2, |
| + 0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD, |
| + 0xBE,0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8, |
| + 0xC9,0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2, |
| + 0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD, |
| + 0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7, |
| + 0xE8,0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1, |
| + 0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB, |
| + 0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x07, |
| + 0x08,0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16, |
| + 0x18,0x1A,0x1C,0x1E,0x20,0x22,0x24,0x26, |
| + 0x28,0x2A,0x2B,0x2D,0x2F,0x31,0x33,0x34, |
| + 0x36,0x38,0x39,0x3B,0x3D,0x3E,0x40,0x42, |
| + 0x43,0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4F, |
| + 0x50,0x52,0x53,0x55,0x56,0x58,0x59,0x5B, |
| + 0x5D,0x5E,0x60,0x61,0x63,0x64,0x66,0x67, |
| + 0x69,0x6A,0x6B,0x6D,0x6E,0x70,0x71,0x73, |
| + 0x74,0x76,0x77,0x79,0x7A,0x7B,0x7D,0x7E, |
| + 0x80,0x81,0x83,0x84,0x85,0x87,0x88,0x8A, |
| + 0x8B,0x8C,0x8E,0x8F,0x90,0x92,0x93,0x95, |
| + 0x96,0x97,0x99,0x9A,0x9B,0x9D,0x9E,0x9F, |
| + 0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,0xAA, |
| + 0xAB,0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,0xB5, |
| + 0xB6,0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF, |
| + 0xC0,0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,0xC9, |
| + 0xCB,0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,0xD4, |
| + 0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,0xDF, |
| + 0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,0xE8,0xE9, |
| + 0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3, |
| + 0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03, |
| + 0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10, |
| + 0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20, |
| + 0x22,0x24,0x26,0x28,0x2A,0x2B,0x2D,0x2F, |
| + 0x31,0x33,0x34,0x36,0x38,0x39,0x3B,0x3D, |
| + 0x3E,0x40,0x42,0x43,0x45,0x47,0x48,0x4A, |
| + 0x4B,0x4D,0x4F,0x50,0x52,0x53,0x55,0x56, |
| + 0x58,0x59,0x5B,0x5D,0x5E,0x60,0x61,0x63, |
| + 0x64,0x66,0x67,0x69,0x6A,0x6B,0x6D,0x6E, |
| + 0x70,0x71,0x73,0x74,0x76,0x77,0x79,0x7A, |
| + 0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84,0x85, |
| + 0x87,0x88,0x8A,0x8B,0x8C,0x8E,0x8F,0x90, |
| + 0x92,0x93,0x95,0x96,0x97,0x99,0x9A,0x9B, |
| + 0x9D,0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,0xA6, |
| + 0xA7,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB1, |
| + 0xB2,0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB, |
| + 0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC6, |
| + 0xC7,0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,0xD0, |
| + 0xD1,0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,0xDA, |
| + 0xDB,0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,0xE5, |
| + 0xE6,0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF, |
| + 0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9, |
| + 0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x01,0x02,0x03,0x04,0x05,0x07,0x08,0x0A, |
| + 0x0C,0x0E,0x10,0x12,0x14,0x16,0x18,0x1A, |
| + 0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A, |
| + 0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38, |
| + 0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45, |
| + 0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52, |
| + 0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E, |
| + 0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A, |
| + 0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76, |
| + 0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81, |
| + 0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C, |
| + 0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97, |
| + 0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA2, |
| + 0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD, |
| + 0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7, |
| + 0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2, |
| + 0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC, |
| + 0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6, |
| + 0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0, |
| + 0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB, |
| + 0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5, |
| + 0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, |
| + 0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E, |
| + 0x10,0x12,0x14,0x16,0x18,0x18,0x1A,0x1C, |
| + 0x1E,0x20,0x22,0x24,0x26,0x27,0x29,0x2B, |
| + 0x2C,0x2E,0x30,0x31,0x33,0x35,0x36,0x38, |
| + 0x39,0x3B,0x3C,0x3E,0x40,0x41,0x43,0x44, |
| + 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50, |
| + 0x51,0x52,0x54,0x55,0x56,0x58,0x59,0x5B, |
| + 0x5C,0x5D,0x5F,0x60,0x61,0x63,0x64,0x65, |
| + 0x67,0x68,0x69,0x6A,0x6C,0x6D,0x6E,0x70, |
| + 0x71,0x72,0x73,0x75,0x76,0x77,0x78,0x7A, |
| + 0x7B,0x7C,0x7D,0x7E,0x80,0x81,0x82,0x83, |
| + 0x85,0x86,0x87,0x88,0x89,0x8A,0x8C,0x8D, |
| + 0x8E,0x8F,0x90,0x92,0x93,0x94,0x95,0x96, |
| + 0x97,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, |
| + 0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8, |
| + 0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1, |
| + 0xB2,0xB3,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA, |
| + 0xBB,0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC4, |
| + 0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC, |
| + 0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5, |
| + 0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD, |
| + 0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5, |
| + 0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED, |
| + 0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5, |
| + 0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { // 7 |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, |
| + 0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C, |
| + 0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C, |
| + 0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A, |
| + 0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37, |
| + 0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44, |
| + 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50, |
| + 0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C, |
| + 0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67, |
| + 0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72, |
| + 0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D, |
| + 0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88, |
| + 0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92, |
| + 0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C, |
| + 0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6, |
| + 0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0, |
| + 0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA, |
| + 0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4, |
| + 0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE, |
| + 0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7, |
| + 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1, |
| + 0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA, |
| + 0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3, |
| + 0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + } |
| +}; |
| + |
| +static unsigned char LUT_B[][256] = |
| +{ |
| + { |
| + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, |
| + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, |
| + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, |
| + 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, |
| + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, |
| + 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, |
| + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, |
| + 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, |
| + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, |
| + 0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, |
| + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, |
| + 0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, |
| + 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67, |
| + 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, |
| + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77, |
| + 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F, |
| + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, |
| + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, |
| + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97, |
| + 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, |
| + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7, |
| + 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, |
| + 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7, |
| + 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, |
| + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7, |
| + 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, |
| + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7, |
| + 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, |
| + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7, |
| + 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, |
| + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7, |
| + 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| + 0x02,0x03,0x04,0x06,0x07,0x09,0x0B,0x0D, |
| + 0x10,0x12,0x14,0x17,0x19,0x1B,0x1E,0x20, |
| + 0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30, |
| + 0x32,0x33,0x35,0x37,0x39,0x3B,0x3C,0x3E, |
| + 0x40,0x41,0x43,0x45,0x46,0x48,0x4A,0x4B, |
| + 0x4D,0x4F,0x50,0x52,0x53,0x55,0x57,0x58, |
| + 0x5A,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64, |
| + 0x66,0x67,0x69,0x6A,0x6C,0x6D,0x6F,0x70, |
| + 0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B, |
| + 0x7D,0x7E,0x7F,0x81,0x82,0x84,0x85,0x86, |
| + 0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x90,0x91, |
| + 0x92,0x94,0x95,0x96,0x98,0x99,0x9A,0x9C, |
| + 0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6, |
| + 0xA7,0xA8,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0, |
| + 0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA, |
| + 0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4, |
| + 0xC5,0xC6,0xC7,0xC9,0xCA,0xCB,0xCC,0xCD, |
| + 0xCF,0xD0,0xD1,0xD2,0xD3,0xD5,0xD6,0xD7, |
| + 0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE0, |
| + 0xE1,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9, |
| + 0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF3, |
| + 0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFB,0xFC, |
| + 0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| + 0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C, |
| + 0x0E,0x10,0x12,0x14,0x16,0x16,0x19,0x1B, |
| + 0x1D,0x1F,0x21,0x23,0x25,0x27,0x28,0x2A, |
| + 0x2C,0x2E,0x30,0x32,0x33,0x35,0x37,0x39, |
| + 0x3A,0x3C,0x3E,0x40,0x41,0x43,0x45,0x46, |
| + 0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52,0x53, |
| + 0x55,0x57,0x58,0x5A,0x5B,0x5D,0x5F,0x60, |
| + 0x62,0x63,0x65,0x66,0x68,0x69,0x6B,0x6C, |
| + 0x6E,0x6F,0x71,0x72,0x74,0x75,0x77,0x78, |
| + 0x7A,0x7B,0x7D,0x7E,0x80,0x81,0x83,0x84, |
| + 0x86,0x87,0x88,0x8A,0x8B,0x8D,0x8E,0x90, |
| + 0x91,0x92,0x94,0x95,0x97,0x98,0x99,0x9B, |
| + 0x9C,0x9E,0x9F,0xA0,0xA2,0xA3,0xA5,0xA7, |
| + 0xA9,0xAA,0xAB,0xAD,0xAE,0xB0,0xB1,0xB2, |
| + 0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBC,0xBD, |
| + 0xBE,0xC0,0xC1,0xC2,0xC4,0xC5,0xC6,0xC8, |
| + 0xC9,0xCA,0xCC,0xCD,0xCE,0xD0,0xD1,0xD2, |
| + 0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB,0xDD, |
| + 0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7, |
| + 0xE8,0xE9,0xEB,0xEC,0xED,0xEF,0xF0,0xF1, |
| + 0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB, |
| + 0xFC,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x01,0x02,0x03,0x04,0x05,0x07,0x08, |
| + 0x0A,0x0C,0x0E,0x10,0x12,0x14,0x16,0x18, |
| + 0x1A,0x1C,0x1E,0x20,0x22,0x24,0x26,0x28, |
| + 0x2A,0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36, |
| + 0x38,0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43, |
| + 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50, |
| + 0x52,0x53,0x55,0x56,0x58,0x59,0x5B,0x5D, |
| + 0x5E,0x60,0x61,0x63,0x64,0x66,0x67,0x69, |
| + 0x6A,0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74, |
| + 0x76,0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80, |
| + 0x81,0x83,0x84,0x85,0x87,0x88,0x8A,0x8B, |
| + 0x8C,0x8E,0x8F,0x90,0x92,0x93,0x95,0x96, |
| + 0x97,0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1, |
| + 0xA2,0xA3,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB, |
| + 0xAD,0xAE,0xAF,0xB1,0xB2,0xB3,0xB5,0xB6, |
| + 0xB7,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0, |
| + 0xC2,0xC3,0xC4,0xC6,0xC7,0xC8,0xC9,0xCB, |
| + 0xCC,0xCD,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5, |
| + 0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,0xDE,0xDF, |
| + 0xE0,0xE1,0xE3,0xE4,0xE5,0xE6,0xE8,0xE9, |
| + 0xEA,0xEB,0xED,0xEE,0xEF,0xF0,0xF2,0xF3, |
| + 0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFD, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04, |
| + 0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10,0x12, |
| + 0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,0x22, |
| + 0x24,0x26,0x28,0x2A,0x2B,0x2D,0x2F,0x31, |
| + 0x33,0x34,0x36,0x38,0x39,0x3B,0x3D,0x3E, |
| + 0x40,0x42,0x43,0x45,0x47,0x48,0x4A,0x4B, |
| + 0x4D,0x4F,0x50,0x52,0x53,0x55,0x56,0x58, |
| + 0x59,0x5B,0x5D,0x5E,0x60,0x61,0x63,0x64, |
| + 0x66,0x67,0x69,0x6A,0x6B,0x6D,0x6E,0x70, |
| + 0x71,0x73,0x74,0x76,0x77,0x79,0x7A,0x7B, |
| + 0x7D,0x7E,0x80,0x81,0x83,0x84,0x85,0x87, |
| + 0x88,0x8A,0x8B,0x8C,0x8E,0x8F,0x90,0x92, |
| + 0x93,0x95,0x96,0x97,0x99,0x9A,0x9B,0x9D, |
| + 0x9E,0x9F,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7, |
| + 0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB1,0xB2, |
| + 0xB3,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBD, |
| + 0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC6,0xC7, |
| + 0xC8,0xC9,0xCB,0xCC,0xCD,0xCF,0xD0,0xD1, |
| + 0xD2,0xD4,0xD5,0xD6,0xD7,0xD9,0xDA,0xDB, |
| + 0xDC,0xDE,0xDF,0xE0,0xE1,0xE3,0xE4,0xE5, |
| + 0xE6,0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF, |
| + 0xF0,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9, |
| + 0xFA,0xFB,0xFD,0xFE,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, |
| + 0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C, |
| + 0x0E,0x10,0x12,0x14,0x16,0x16,0x18,0x1A, |
| + 0x1C,0x1E,0x20,0x22,0x24,0x26,0x28,0x2A, |
| + 0x2B,0x2D,0x2F,0x31,0x33,0x34,0x36,0x38, |
| + 0x39,0x3B,0x3D,0x3E,0x40,0x42,0x43,0x45, |
| + 0x47,0x48,0x4A,0x4B,0x4D,0x4F,0x50,0x52, |
| + 0x53,0x55,0x56,0x58,0x59,0x5B,0x5D,0x5E, |
| + 0x60,0x61,0x63,0x64,0x66,0x67,0x69,0x6A, |
| + 0x6B,0x6D,0x6E,0x70,0x71,0x73,0x74,0x76, |
| + 0x77,0x79,0x7A,0x7B,0x7D,0x7E,0x80,0x81, |
| + 0x83,0x84,0x85,0x87,0x88,0x8A,0x8B,0x8C, |
| + 0x8E,0x8F,0x90,0x92,0x93,0x95,0x96,0x97, |
| + 0x99,0x9A,0x9B,0x9D,0x9E,0x9F,0xA1,0xA3, |
| + 0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAD,0xAE, |
| + 0xAF,0xB1,0xB2,0xB3,0xB5,0xB6,0xB7,0xB9, |
| + 0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3, |
| + 0xC4,0xC6,0xC7,0xC8,0xC9,0xCB,0xCC,0xCD, |
| + 0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6,0xD7, |
| + 0xD9,0xDA,0xDB,0xDC,0xDE,0xDF,0xE0,0xE1, |
| + 0xE3,0xE4,0xE5,0xE6,0xE8,0xE9,0xEA,0xEB, |
| + 0xED,0xEE,0xEF,0xF0,0xF2,0xF3,0xF4,0xF5, |
| + 0xF6,0xF8,0xF9,0xFA,0xFB,0xFD,0xFE,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03, |
| + 0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E,0x10, |
| + 0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20, |
| + 0x22,0x24,0x26,0x27,0x29,0x2B,0x2C,0x2E, |
| + 0x30,0x31,0x33,0x35,0x36,0x38,0x39,0x3B, |
| + 0x3C,0x3E,0x40,0x41,0x43,0x44,0x45,0x47, |
| + 0x48,0x4B,0x4D,0x4E,0x50,0x51,0x52,0x54, |
| + 0x55,0x56,0x58,0x59,0x5B,0x5C,0x5D,0x5F, |
| + 0x60,0x61,0x63,0x64,0x65,0x67,0x68,0x69, |
| + 0x6A,0x6C,0x6D,0x6E,0x70,0x71,0x72,0x73, |
| + 0x75,0x76,0x77,0x78,0x7A,0x7B,0x7C,0x7D, |
| + 0x7E,0x80,0x81,0x82,0x83,0x85,0x86,0x87, |
| + 0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x90, |
| + 0x92,0x93,0x94,0x95,0x96,0x96,0x97,0x99, |
| + 0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA1,0xA2, |
| + 0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB, |
| + 0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3, |
| + 0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC, |
| + 0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC5, |
| + 0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD, |
| + 0xCE,0xCF,0xD0,0xD1,0xD2,0xD4,0xD5,0xD6, |
| + 0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE, |
| + 0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6, |
| + 0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE, |
| + 0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6, |
| + 0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + }, |
| + { |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
| + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, |
| + 0x03,0x04,0x05,0x06,0x07,0x09,0x0B,0x0C, |
| + 0x0E,0x10,0x12,0x14,0x16,0x18,0x1A,0x1C, |
| + 0x1E,0x20,0x21,0x23,0x25,0x27,0x28,0x2A, |
| + 0x2C,0x2D,0x2F,0x31,0x32,0x34,0x36,0x37, |
| + 0x39,0x3B,0x3C,0x3E,0x3F,0x41,0x42,0x44, |
| + 0x45,0x47,0x48,0x4A,0x4B,0x4D,0x4E,0x50, |
| + 0x51,0x53,0x54,0x56,0x57,0x59,0x5A,0x5C, |
| + 0x5D,0x5F,0x60,0x61,0x63,0x64,0x66,0x67, |
| + 0x68,0x6A,0x6B,0x6D,0x6E,0x6F,0x71,0x72, |
| + 0x73,0x75,0x76,0x78,0x79,0x7A,0x7C,0x7D, |
| + 0x7E,0x80,0x81,0x82,0x84,0x85,0x86,0x88, |
| + 0x89,0x8A,0x8B,0x8D,0x8E,0x8F,0x91,0x92, |
| + 0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C, |
| + 0x9E,0x9F,0xA0,0xA1,0xA3,0xA4,0xA5,0xA6, |
| + 0xA8,0xA9,0xAA,0xAB,0xAD,0xAE,0xAF,0xB0, |
| + 0xB2,0xB3,0xB4,0xB5,0xB7,0xB8,0xB9,0xBA, |
| + 0xBC,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4, |
| + 0xC5,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE, |
| + 0xCF,0xD0,0xD1,0xD3,0xD4,0xD5,0xD6,0xD7, |
| + 0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xE0,0xE1, |
| + 0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEA, |
| + 0xEB,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3, |
| + 0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFC,0xFD, |
| + 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, |
| + } |
| +}; |
| +//// profile array //// |
| + |
| +typedef struct |
| +{ |
| + int productID; // USB PID |
| + char productName[50]; // ESCI/2 procduct name |
| + char deviceID[50]; // device ID (same as bonjour mdl name) |
| + int lutID; // look up table no |
| +}epsonds_profile_map; |
| + |
| +const epsonds_profile_map epsonds_models_predefined[] = { |
| + {0x0145, "DS-5500","DS-5500", 7}, |
| + {0x0145, "DS-6500","DS-6500", 7}, |
| + {0x0145, "DS-7500","DS-7500", 7}, |
| + {0x0146, "DS-50000","DS-50000", 7}, |
| + {0x0146, "DS-60000","DS-60000", 7}, |
| + {0x0146, "DS-70000","DS-70000", 7}, |
| + {0x014C, "DS-510","DS-510", 7}, |
| + {0x0150, "DS-560","DS-560", 7}, |
| + {0x0152, "DS-40","DS-40", 7}, |
| + {0x014D, "DS-760","DS-760", 7}, |
| + {0x014D, "DS-860","DS-860", 7}, |
| + {0x0154, "DS-520","DS-520", 7}, |
| + {0x08BC, "PID 08BC","PX-M7050 Series", 7}, |
| + {0x08BC, "PID 08BC","WF-8510 Series", 7}, |
| + {0x08BC, "PID 08BC","WF-8590 Series", 7}, |
| + {0x08CC, "PID 08CC","PX-M7050FX Series", 7}, |
| + {0x08CC, "PID 08CC","WF-R8590 Series", 7}, |
| + {0x0165, "DS-410","DS-410", 7}, |
| + {0x016C, "ES-50","ES-50", 6}, |
| + {0x0160, "DS-70","DS-70", 6}, |
| + {0x016D, "ES-55R","ES-55R", 6}, |
| + {0x018C, "RR-60","RR-60", 6}, |
| + {0x016E, "ES-60W","ES-60W", 6}, |
| + {0x0166, "DS-80W","DS-80W", 6}, |
| + {0x016F, "ES-65WR","ES-65WR", 6}, |
| + {0x018B, "RR-70W","RR-70W", 6}, |
| + {0x016E, "ES-60WW","ES-60WW", 6}, |
| + {0x016E, "ES-60WB","ES-60WB", 6}, |
| + {0x015C, "DS-1630","DS-1630", 4}, |
| + {0x015D, "DS-1610","DS-1610", 4}, |
| + {0x015E, "DS-1660W","DS-1660W", 4}, |
| + {0x0159, "DS-310","DS-310", 5}, |
| + {0x0159, "ES-200","ES-200", 5}, |
| + {0x0162, "DS-320","DS-320", 5}, |
| + {0x015A, "DS-360W","DS-360W", 5}, |
| + {0x015A, "ES-300W","ES-300W", 5}, |
| + {0x0177, "ES-300WR","ES-300WR", 5}, |
| + {0x0181, "ES-400II","ES-400II", 2}, |
| + {0x0183, "DS-535II","DS-535II", 2}, |
| + {0x0184, "DS-531","DS-531", 2}, |
| + {0x0182, "DS-530II","DS-530II", 2}, |
| + {0x0185, "ES-500WII","ES-500WII", 2}, |
| + {0x0188, "DS-571W","DS-571W", 2}, |
| + {0x0187, "DS-575WII","DS-575WII", 2}, |
| + {0x0186, "DS-570WII","DS-570WII", 2}, |
| + {0x017F, "ES-580W","ES-580W", 2}, |
| + {0x0180, "RR-600W","RR-600W", 2}, |
| + {0x0167, "DS-535","DS-535", 2}, |
| + {0x017A, "DS-535H","DS-535H", 2}, |
| + {0x0156, "ES-400","ES-400", 2}, |
| + {0x0155, "DS-530","DS-530", 2}, |
| + {0x016B, "FF-680W","FF-680W", 2}, |
| + {0x0157, "DS-570W","DS-570W", 2}, |
| + {0x0157, "ES-500W","ES-500W", 2}, |
| + {0x0169, "DS-575W","DS-575W", 2}, |
| + {0x0176, "ES-500WR","ES-500WR", 2}, |
| + {0x114E, "PID 114E","EW-052A Series", 7}, |
| + {0x114E, "PID 114E","XP-2100 Series", 7}, |
| + {0x1135, "PID 1135","ET-2700 Series", 7}, |
| + {0x1135, "PID 1135","L4150 Series", 7}, |
| + {0x114A, "PID 114A","ET-M2140 Series", 7}, |
| + {0x114A, "PID 114A","M2140 Series", 7}, |
| + {0x114F, "PID 114F","ET-M3140 Series", 7}, |
| + {0x114F, "PID 114F","M3140 Series", 7}, |
| + {0x1143, "PID 1143","L3150 Series", 7}, |
| + {0x1143, "PID 1143","ET-2710 Series", 7}, |
| + {0x00, "","", 0x00 } |
| +}; |
| + |
| +typedef struct |
| +{ |
| + epsonds_profile_map *array; |
| + int used; |
| + int size; |
| +}epsonds_profile_map_array; |
| + |
| + |
| +static epsonds_profile_map_array stProfileMapArray; |
| + |
| +static void insert_profile_map(epsonds_profile_map_array *a, epsonds_profile_map element); |
| + |
| +static void init_profile_maps(epsonds_profile_map_array *a, size_t initialSize) { |
| + a->array = malloc(initialSize * sizeof(epsonds_profile_map)); |
| + a->used = 0; |
| + a->size = initialSize; |
| + |
| + for (int i = 0; epsonds_models_predefined[i].productID != 0; i++) { |
| + |
| + //DBG(6, "epsonds_models_predefined[i].productID = %x\n", epsonds_models_predefined[i].productID ); |
| + |
| + insert_profile_map(a, epsonds_models_predefined[i]); |
| + } |
| +} |
| + |
| +static void insert_profile_map(epsonds_profile_map_array *a, epsonds_profile_map element) { |
| + if (a->used == a->size) { |
| + a->size *= 2; |
| + a->array = realloc(a->array, a->size * sizeof(epsonds_profile_map)); |
| + } |
| + a->array[a->used++] = element; |
| +} |
| + |
| +static void free_profile_maps(epsonds_profile_map_array *a) { |
| + free(a->array); |
| + a->array = NULL; |
| + a->used = a->size = 0; |
| +} |
| +///////////////////////// |
| + |
| + |
| struct mode_param mode_params[] = { |
| {0, 0x00, 0x30, 1}, |
| {0, 0x00, 0x30, 8}, |
| @@ -86,16 +1313,12 @@ static SANE_String_Const mode_list[] = { |
| NULL |
| }; |
| |
| -static const SANE_String_Const adf_mode_list[] = { |
| - SANE_I18N("Simplex"), |
| - SANE_I18N("Duplex"), |
| - NULL |
| -}; |
| |
| /* Define the different scan sources */ |
| |
| -#define FBF_STR SANE_I18N("Flatbed") |
| -#define ADF_STR SANE_I18N("Automatic Document Feeder") |
| +#define STRING_FLATBED SANE_I18N("Flatbed") |
| +#define STRING_ADFFRONT SANE_I18N("ADF Front") |
| +#define STRING_ADFDUPLEX SANE_I18N("ADF Duplex") |
| |
| /* order will be fixed: fb, adf, tpu */ |
| SANE_String_Const source_list[] = { |
| @@ -129,6 +1352,9 @@ max_string_size(const SANE_String_Const strings[]) |
| |
| static SANE_Status attach_one_usb(SANE_String_Const devname); |
| static SANE_Status attach_one_net(SANE_String_Const devname); |
| +static SANE_Status acquire_jpeg_data(epsonds_scanner* s); |
| +static SANE_Status acquire_and_decode_jpeg_data(epsonds_scanner* s); |
| +static SANE_Status acquire_raw_data(epsonds_scanner* s); |
| |
| static void |
| print_params(const SANE_Parameters params) |
| @@ -146,6 +1372,11 @@ close_scanner(epsonds_scanner *s) |
| { |
| DBG(7, "%s: fd = %d\n", __func__, s->fd); |
| |
| + if (s->scanning) |
| + { |
| + sane_cancel(s); |
| + } |
| + |
| if (s->fd == -1) |
| goto free; |
| |
| @@ -171,49 +1402,6 @@ free: |
| DBG(7, "%s: ZZZ\n", __func__); |
| } |
| |
| -static void |
| -e2_network_discovery(void) |
| -{ |
| - fd_set rfds; |
| - int fd, len; |
| - SANE_Status status; |
| - |
| - char *ip, *query = "EPSONP\x00\xff\x00\x00\x00\x00\x00\x00\x00"; |
| - unsigned char buf[76]; |
| - |
| - struct timeval to; |
| - |
| - status = sanei_udp_open_broadcast(&fd); |
| - if (status != SANE_STATUS_GOOD) |
| - return; |
| - |
| - sanei_udp_write_broadcast(fd, 3289, (unsigned char *) query, 15); |
| - |
| - DBG(5, "%s, sent discovery packet\n", __func__); |
| - |
| - to.tv_sec = 1; |
| - to.tv_usec = 0; |
| - |
| - FD_ZERO(&rfds); |
| - FD_SET(fd, &rfds); |
| - |
| - sanei_udp_set_nonblock(fd, SANE_TRUE); |
| - while (select(fd + 1, &rfds, NULL, NULL, &to) > 0) { |
| - if ((len = sanei_udp_recvfrom(fd, buf, 76, &ip)) == 76) { |
| - DBG(5, " response from %s\n", ip); |
| - |
| - /* minimal check, protocol unknown */ |
| - if (strncmp((char *) buf, "EPSON", 5) == 0) |
| - attach_one_net(ip); |
| - } |
| - } |
| - |
| - DBG(5, "%s, end\n", __func__); |
| - |
| - sanei_udp_close(fd); |
| -} |
| - |
| - |
| static SANE_Status |
| open_scanner(epsonds_scanner *s) |
| { |
| @@ -230,7 +1418,7 @@ open_scanner(epsonds_scanner *s) |
| unsigned char buf[5]; |
| |
| /* device name has the form net:ipaddr */ |
| - status = sanei_tcp_open(&s->hw->sane.name[4], 1865, &s->fd); |
| + status = sanei_tcp_open(&s->hw->name[4], 1865, &s->fd); |
| if (status == SANE_STATUS_GOOD) { |
| |
| ssize_t read; |
| @@ -272,12 +1460,10 @@ open_scanner(epsonds_scanner *s) |
| } |
| |
| } else if (s->hw->connection == SANE_EPSONDS_USB) { |
| - |
| status = sanei_usb_open(s->hw->sane.name, &s->fd); |
| |
| if (status == SANE_STATUS_GOOD) { |
| sanei_usb_set_timeout(USB_TIMEOUT); |
| - sanei_usb_clear_halt(s->fd); |
| } |
| |
| } else { |
| @@ -307,7 +1493,6 @@ static struct epsonds_scanner * |
| scanner_create(struct epsonds_device *dev, SANE_Status *status) |
| { |
| struct epsonds_scanner *s; |
| - |
| s = malloc(sizeof(struct epsonds_scanner)); |
| if (s == NULL) { |
| *status = SANE_STATUS_NO_MEM; |
| @@ -428,7 +1613,32 @@ device_detect(const char *name, int type, SANE_Status *status) |
| |
| DBG(1, "scanner model: %s\n", dev->model); |
| |
| - /* add this scanner to the device list */ |
| + |
| + s->hw->lut_id = 0; |
| + |
| + for (int i = 0; i < stProfileMapArray.used; i++) { |
| + |
| + epsonds_profile_map* map = &stProfileMapArray.array[i]; |
| + |
| + |
| + if (strcmp(map->productName, dev->model) == 0) { |
| + |
| + {//Convert to user friendly model name |
| + free(s->hw->model); |
| + |
| + char* deviceName = (char*)malloc(strlen(map->deviceID) + 1); |
| + memset(deviceName, 0, strlen(map->deviceID) + 1); |
| + strncpy(deviceName, map->deviceID, strlen(map->deviceID)); |
| + s->hw->model = deviceName; |
| + s->hw->sane.model = s->hw->model; |
| + } |
| + {// set lutid |
| + s->hw->lut_id = map->lutID; |
| + } |
| + break; |
| + } |
| + } |
| + DBG(1, "scanner lut_id: %d\n", s->hw->lut_id); |
| |
| num_devices++; |
| dev->next = first_dev; |
| @@ -479,6 +1689,67 @@ attach_one_net(const char *dev) |
| return attach(name, SANE_EPSONDS_NET); |
| } |
| |
| +static void found_net_device(const char* device_name, const char* ip) |
| +{ |
| + DBG(7, "Found %s: ip = %s\n", device_name, ip); |
| + |
| + int foundSupportedDevice = 0; |
| + |
| + // search models |
| + for (int i = 0; i < stProfileMapArray.used; i++) { |
| + if (strcmp(stProfileMapArray.array[i].deviceID, device_name) == 0) { |
| + foundSupportedDevice = 1; |
| + break; |
| + } |
| + } |
| + |
| + |
| + if (foundSupportedDevice) |
| + { |
| + char name[39 + 4]; |
| + |
| + strcpy(name, "net:"); |
| + strncat(name, ip, 39); |
| + |
| + int foundCache = 0; |
| + // search cache and prents duplicated model |
| + for (epsonds_device* dev = first_dev; dev; dev = dev->next) { |
| + if (strcmp(dev->sane.name, name) == 0) { |
| + foundCache = 1; |
| + } |
| + } |
| + if (foundCache == 0) |
| + { |
| + attach(name, SANE_EPSONDS_NET); |
| + } |
| + } |
| +} |
| + |
| +static void |
| +splitProfileName(const char* input, int* outProductID, char *outProductName, char* outDeviceID, int* outLutID) |
| +{ |
| + char target[1024]; |
| + strncpy(target, input, 1023); |
| + |
| + strtok(target, ":");//profile |
| + |
| + //productID |
| + char* pid = strtok(NULL, ","); |
| + sscanf(pid, "%x", (unsigned int*)outProductID); |
| + |
| + //productName |
| + char* productName = strtok(NULL, ","); |
| + strncpy(outProductName, productName, 49); |
| + |
| + //deviceID |
| + char* deviceID = strtok(NULL, ","); |
| + strncpy(outDeviceID, deviceID, 49); |
| + |
| + //lutID |
| + char* lutID = strtok(NULL, ","); |
| + sscanf(lutID, "%d", outLutID); |
| +} |
| + |
| |
| static SANE_Status |
| attach_one_config(SANEI_Config __sane_unused__ *config, const char *line, |
| @@ -489,8 +1760,17 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line, |
| int len = strlen(line); |
| |
| DBG(7, "%s: len = %d, line = %s\n", __func__, len, line); |
| + if (strncmp(line, "profile", 7) == 0 ) { |
| + DBG(7, " found profile device profile\n"); |
| |
| - if (sscanf(line, "usb %i %i", &vendor, &product) == 2) { |
| + epsonds_profile_map profle_map; |
| + |
| + splitProfileName(line, &profle_map.productID, profle_map.productName, profle_map.deviceID, &profle_map.lutID); |
| + |
| + DBG(7, "Found profile : %x %s %s %d\n", profle_map.productID, profle_map.productName, profle_map.deviceID, profle_map.lutID); |
| + |
| + insert_profile_map(&stProfileMapArray, profle_map); |
| + }else if (sscanf(line, "usb %i %i", &vendor, &product) == 2) { |
| |
| DBG(7, " user configured device\n"); |
| |
| @@ -501,15 +1781,11 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line, |
| |
| } else if (strncmp(line, "usb", 3) == 0 && len == 3) { |
| |
| - int i, numIds; |
| - |
| DBG(7, " probing usb devices\n"); |
| |
| - numIds = epsonds_get_number_of_ids(); |
| - |
| - for (i = 0; i < numIds; i++) { |
| - sanei_usb_find_devices(SANE_EPSONDS_VENDOR_ID, |
| - epsonds_usb_product_ids[i], attach_one_usb); |
| + for (int i = 0; i < stProfileMapArray.used; i++) { |
| + int usbPid = stProfileMapArray.array[i].productID; |
| + sanei_usb_find_devices(SANE_EPSONDS_VENDOR_ID, usbPid, attach_one_usb); |
| } |
| |
| } else if (strncmp(line, "net", 3) == 0) { |
| @@ -520,11 +1796,17 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line, |
| sanei_config_skip_whitespace(line + 3); |
| |
| if (strncmp(name, "autodiscovery", 13) == 0) |
| - e2_network_discovery(); |
| + { |
| + #if WITH_AVAHI |
| + epsonds_searchDevices(found_net_device); |
| + #else |
| + // currently does not support |
| + //e2_network_discovery(); |
| + #endif |
| + } |
| else |
| attach_one_net(name); |
| } |
| - |
| } else { |
| DBG(0, "unable to parse config line: %s\n", line); |
| } |
| @@ -564,6 +1846,9 @@ SANE_Status |
| sane_init(SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize) |
| { |
| DBG_INIT(); |
| + |
| + init_profile_maps(&stProfileMapArray, 100); |
| + |
| DBG(2, "%s: " PACKAGE " " VERSION "\n", __func__); |
| |
| DBG(1, "epsonds backend, version %i.%i.%i\n", |
| @@ -582,6 +1867,7 @@ void |
| sane_exit(void) |
| { |
| DBG(5, "** %s\n", __func__); |
| + free_profile_maps(&stProfileMapArray); |
| free_devices(); |
| } |
| |
| @@ -591,7 +1877,8 @@ sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only) |
| int i; |
| epsonds_device *dev; |
| |
| - DBG(5, "** %s\n", __func__); |
| + DBG(5, "** %s local_only = %d \n", __func__, local_only); |
| + |
| |
| probe_devices(local_only); |
| |
| @@ -612,12 +1899,14 @@ sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only) |
| |
| *device_list = devlist; |
| |
| + |
| return SANE_STATUS_GOOD; |
| } |
| |
| static SANE_Status |
| init_options(epsonds_scanner *s) |
| { |
| + DBG(5, "init_options\n"); |
| int i; |
| |
| for (i = 0; i < NUM_OPTIONS; i++) { |
| @@ -632,11 +1921,11 @@ init_options(epsonds_scanner *s) |
| s->val[OPT_NUM_OPTS].w = NUM_OPTIONS; |
| |
| /* "Scan Mode" group: */ |
| - |
| - s->opt[OPT_MODE_GROUP].title = SANE_I18N("Scan Mode"); |
| - s->opt[OPT_MODE_GROUP].desc = ""; |
| - s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; |
| - s->opt[OPT_MODE_GROUP].cap = 0; |
| + s->opt[OPT_STANDARD_GROUP].name = SANE_NAME_STANDARD; |
| + s->opt[OPT_STANDARD_GROUP].title = SANE_TITLE_STANDARD; |
| + s->opt[OPT_STANDARD_GROUP].desc = SANE_DESC_STANDARD; |
| + s->opt[OPT_STANDARD_GROUP].type = SANE_TYPE_GROUP; |
| + s->opt[OPT_STANDARD_GROUP].cap = 0; |
| |
| /* scan mode */ |
| s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; |
| @@ -761,18 +2050,6 @@ init_options(epsonds_scanner *s) |
| if (!s->hw->adf_has_load) |
| s->opt[OPT_LOAD].cap |= SANE_CAP_INACTIVE; |
| |
| - s->opt[OPT_ADF_MODE].name = "adf-mode"; |
| - s->opt[OPT_ADF_MODE].title = SANE_I18N("ADF Mode"); |
| - s->opt[OPT_ADF_MODE].desc = |
| - SANE_I18N("Selects the ADF mode (simplex/duplex)"); |
| - s->opt[OPT_ADF_MODE].type = SANE_TYPE_STRING; |
| - s->opt[OPT_ADF_MODE].size = max_string_size(adf_mode_list); |
| - s->opt[OPT_ADF_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; |
| - s->opt[OPT_ADF_MODE].constraint.string_list = adf_mode_list; |
| - s->val[OPT_ADF_MODE].w = 0; /* simplex */ |
| - |
| - if (!s->hw->adf_is_duplex) |
| - s->opt[OPT_ADF_MODE].cap |= SANE_CAP_INACTIVE; |
| |
| s->opt[OPT_ADF_SKEW].name = "adf-skew"; |
| s->opt[OPT_ADF_SKEW].title = SANE_I18N("ADF Skew Correction"); |
| @@ -781,8 +2058,26 @@ init_options(epsonds_scanner *s) |
| s->opt[OPT_ADF_SKEW].type = SANE_TYPE_BOOL; |
| s->val[OPT_ADF_SKEW].w = 0; |
| |
| + |
| + s->opt[OPT_ADF_CRP].name = "adf-crp"; |
| + s->opt[OPT_ADF_CRP].title = SANE_I18N("ADF CRP Correction"); |
| + s->opt[OPT_ADF_CRP].desc = |
| + SANE_I18N("Enables ADF auto cropping"); // |
| + s->opt[OPT_ADF_CRP].type = SANE_TYPE_BOOL; |
| + s->val[OPT_ADF_CRP].w = 0; |
| + |
| + |
| if (!s->hw->adf_has_skew) |
| + { |
| + s->val[OPT_ADF_SKEW].w = 0; |
| s->opt[OPT_ADF_SKEW].cap |= SANE_CAP_INACTIVE; |
| + } |
| + |
| + if(!s->hw->adf_has_crp) |
| + { |
| + s->val[OPT_ADF_CRP].w = 0; |
| + s->opt[OPT_ADF_CRP].cap |= SANE_CAP_INACTIVE; |
| + } |
| |
| return SANE_STATUS_GOOD; |
| } |
| @@ -793,6 +2088,8 @@ sane_open(SANE_String_Const name, SANE_Handle *handle) |
| SANE_Status status; |
| epsonds_scanner *s = NULL; |
| |
| + |
| + |
| DBG(7, "** %s: name = '%s'\n", __func__, name); |
| |
| /* probe if empty device name provided */ |
| @@ -848,6 +2145,8 @@ sane_open(SANE_String_Const name, SANE_Handle *handle) |
| status = eds_lock(s); |
| } |
| |
| + setvalue((SANE_Handle)s, OPT_MODE, (void*)SANE_VALUE_SCAN_MODE_COLOR, NULL); |
| + |
| return status; |
| } |
| |
| @@ -881,24 +2180,6 @@ search_string_list(const SANE_String_Const *list, SANE_String value) |
| return ((*list == NULL) ? NULL : list); |
| } |
| |
| -static void |
| -activateOption(epsonds_scanner *s, SANE_Int option, SANE_Bool *change) |
| -{ |
| - if (!SANE_OPTION_IS_ACTIVE(s->opt[option].cap)) { |
| - s->opt[option].cap &= ~SANE_CAP_INACTIVE; |
| - *change = SANE_TRUE; |
| - } |
| -} |
| - |
| -static void |
| -deactivateOption(epsonds_scanner *s, SANE_Int option, SANE_Bool *change) |
| -{ |
| - if (SANE_OPTION_IS_ACTIVE(s->opt[option].cap)) { |
| - s->opt[option].cap |= SANE_CAP_INACTIVE; |
| - *change = SANE_TRUE; |
| - } |
| -} |
| - |
| /* |
| * Handles setting the source (flatbed, transparency adapter (TPU), |
| * or auto document feeder (ADF)). |
| @@ -911,7 +2192,6 @@ static void |
| change_source(epsonds_scanner *s, SANE_Int optindex, char *value) |
| { |
| int force_max = SANE_FALSE; |
| - SANE_Bool dummy; |
| |
| DBG(1, "%s: optindex = %d, source = '%s'\n", __func__, optindex, |
| value); |
| @@ -928,26 +2208,17 @@ change_source(epsonds_scanner *s, SANE_Int optindex, char *value) |
| force_max = SANE_TRUE; |
| } |
| |
| - if (strcmp(ADF_STR, value) == 0) { |
| - |
| + if (strcmp(STRING_ADFFRONT, value) == 0 || strcmp(STRING_ADFDUPLEX, value) == 0) { |
| s->hw->x_range = &s->hw->adf_x_range; |
| s->hw->y_range = &s->hw->adf_y_range; |
| s->hw->alignment = s->hw->adf_alignment; |
| |
| - if (s->hw->adf_is_duplex) { |
| - activateOption(s, OPT_ADF_MODE, &dummy); |
| - } else { |
| - deactivateOption(s, OPT_ADF_MODE, &dummy); |
| - s->val[OPT_ADF_MODE].w = 0; |
| - } |
| |
| } else if (strcmp(TPU_STR, value) == 0) { |
| |
| s->hw->x_range = &s->hw->tpu_x_range; |
| s->hw->y_range = &s->hw->tpu_y_range; |
| |
| - deactivateOption(s, OPT_ADF_MODE, &dummy); |
| - |
| } else { |
| |
| /* neither ADF nor TPU active, assume FB */ |
| @@ -995,7 +2266,6 @@ getvalue(SANE_Handle handle, SANE_Int option, void *value) |
| break; |
| |
| case OPT_MODE: |
| - case OPT_ADF_MODE: |
| case OPT_SOURCE: |
| strcpy((char *) value, sopt->constraint.string_list[sval->w]); |
| break; |
| @@ -1045,12 +2315,9 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) |
| |
| switch (option) { |
| |
| - case OPT_ADF_MODE: /* simple lists */ |
| - sval->w = optindex; |
| - break; |
| - |
| case OPT_ADF_SKEW: |
| case OPT_RESOLUTION: |
| + case OPT_ADF_CRP: |
| sval->w = *((SANE_Word *) value); |
| reload = SANE_TRUE; |
| break; |
| @@ -1064,9 +2331,29 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) |
| // fall through |
| case OPT_TL_X: |
| case OPT_TL_Y: |
| + |
| sval->w = *((SANE_Word *) value); |
| if (NULL != info) |
| *info |= SANE_INFO_RELOAD_PARAMS; |
| + |
| + if (option == OPT_BR_X) |
| + { |
| + DBG(17, "OPT_BR_X = %d\n", sval->w); |
| + } |
| + if (option == OPT_BR_Y) |
| + { |
| + DBG(17, "OPT_BR_Y = %d\n", sval->w); |
| + } |
| + if (option == OPT_TL_X) |
| + { |
| + DBG(17, "OPT_TL_X = %d\n", sval->w); |
| + } |
| + if (option == OPT_TL_Y) |
| + { |
| + DBG(17, "OPT_TL_Y = %d\n", sval->w); |
| + } |
| + // adf crop set to off |
| + s->val[OPT_ADF_CRP].w = 0; |
| break; |
| |
| case OPT_SOURCE: |
| @@ -1076,6 +2363,8 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) |
| |
| case OPT_MODE: |
| { |
| + DBG(17, " OPT_MODE = index %d\n", optindex); |
| + |
| /* use JPEG mode if RAW is not available when bpp > 1 */ |
| if (optindex > 0 && !s->hw->has_raw) { |
| s->mode_jpeg = 1; |
| @@ -1152,6 +2441,183 @@ sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, |
| return SANE_STATUS_INVAL; |
| } |
| |
| + |
| +static void setBit (SANE_Byte* bytes, SANE_Int bitIndex, SANE_Bool isTrue) |
| +{ |
| + SANE_Int octet = bitIndex / 8; |
| + SANE_Byte bit = 7 - (bitIndex % 8); |
| + |
| + if (isTrue) { |
| + bytes[octet] |= (1 << bit); |
| + } else { |
| + bytes[octet] &= ~(1 << bit); |
| + } |
| +} |
| + |
| +static SANE_Bool getBit (SANE_Byte* bytes, SANE_Int bitIndex) |
| +{ |
| + SANE_Int octet = bitIndex / 8; |
| + SANE_Byte mask = 1 << (7 - (bitIndex % 8)); |
| + |
| + if( bytes[octet] & mask ){ |
| + return SANE_TRUE; |
| + } |
| + |
| + return SANE_FALSE; |
| +} |
| + |
| +static void swapPixel1(SANE_Int x1, |
| + SANE_Int y1, |
| + SANE_Int x2, |
| + SANE_Int y2, |
| + SANE_Byte* bytes, |
| + SANE_Byte bitsPerSample, |
| + SANE_Int samplesPerPixel, |
| + SANE_Int bytesPerRow) |
| +{ |
| + SANE_Int pixelBits = bitsPerSample * samplesPerPixel; |
| + SANE_Int widthBits = bytesPerRow * 8; |
| + |
| + SANE_Byte temp = getBit(bytes, widthBits * y1 + x1 * pixelBits); |
| + { |
| + SANE_Byte right = getBit(bytes, widthBits * y2 + x2 * pixelBits); |
| + setBit(bytes, widthBits * y1 + x1 * pixelBits, right); |
| + } |
| + setBit(bytes, widthBits * y2 + x2 * pixelBits, temp); |
| +} |
| + |
| +static void swapPixel8(SANE_Int x1, |
| + SANE_Int y1, |
| + SANE_Int x2, |
| + SANE_Int y2, |
| + SANE_Byte* bytes, |
| + SANE_Byte bitsPerSample, |
| + SANE_Int samplesPerPixel, |
| + SANE_Int bytesPerRow) |
| +{ |
| + SANE_Int pixelBytes = samplesPerPixel * bitsPerSample / 8; |
| + |
| + for (SANE_Byte i = 0; i < pixelBytes; i++) { |
| + SANE_Byte temp = bytes[y1 * bytesPerRow + (pixelBytes * x1 + i)]; |
| + bytes[y1 * bytesPerRow + (pixelBytes * x1 + i)] = bytes[y2 * bytesPerRow + (pixelBytes * x2 + i)]; |
| + bytes[y2 * bytesPerRow + (pixelBytes * x2 + i)] = temp; |
| + } |
| +} |
| + |
| + |
| + |
| +static void swapPixel(SANE_Int x1, |
| + SANE_Int y1, |
| + SANE_Int x2, |
| + SANE_Int y2, |
| + SANE_Byte* bytes, |
| + SANE_Byte bitsPerSample, |
| + SANE_Int samplesPerPixel, |
| + SANE_Int bytesPerRow) |
| +{ |
| + if (bitsPerSample == 1) { |
| + swapPixel1(x1, y1, x2, y2, bytes, bitsPerSample, samplesPerPixel, bytesPerRow); |
| + }else if(bitsPerSample == 8 || bitsPerSample == 16){ |
| + swapPixel8(x1, y1, x2, y2, bytes, bitsPerSample, samplesPerPixel, bytesPerRow); |
| + } |
| +} |
| + |
| + |
| +void |
| +upside_down_backside_image(epsonds_scanner *s) |
| +{ |
| + // get all data from ring_buffer |
| + if (eds_ring_avail(&s->back) && |
| + (strcmp(s->hw->sane.model, (char*)"DS-1630") == 0 |
| + || strcmp(s->hw->sane.model, (char*)"DS-1610") == 0 |
| + || strcmp(s->hw->sane.model, (char*)"DS-1660W") == 0)) |
| + { |
| + SANE_Int bytesPerLine = s->params.bytes_per_line; |
| + SANE_Int imageSize = bytesPerLine * s->height_back; |
| + |
| + SANE_Byte* workBuffer = malloc(imageSize); |
| + // if there is not enough memory, do nothing. |
| + if (workBuffer) |
| + { |
| + eds_ring_read(&s->back, workBuffer, imageSize); |
| + SANE_Int samplesPerPxel = 3; |
| + if (s->params.format == SANE_FRAME_RGB) |
| + { |
| + samplesPerPxel = 3; |
| + } |
| + else if (s->params.format == SANE_FRAME_GRAY) |
| + { |
| + samplesPerPxel = 1; |
| + } |
| + |
| + SANE_Int half = (s->height_back / 2) - 1; |
| + if (half < 0) { |
| + half = 0; |
| + } |
| + |
| + if((s->height_back % 2) == 1) { |
| + SANE_Int ymid = ( (s->height_back - 1 ) / 2 ); |
| + for(SANE_Int x = 0;x < (s->width_back / 2); x++) { |
| + swapPixel(x, ymid, s->width_back - x - 1, ymid, workBuffer, s->params.depth, samplesPerPxel, s->params.bytes_per_line); |
| + } |
| + } |
| + |
| + if (s->height_back != 1) { |
| + for(SANE_Int x = 0; x < s->width_back; x++) { |
| + for(SANE_Int y = 0;y <= half; y++) { |
| + swapPixel(x, y, s->width_back - x - 1, s->height_back - y -1, workBuffer, s->params.depth, samplesPerPxel, s->params.bytes_per_line); |
| + } |
| + } |
| + } |
| + |
| + eds_ring_write(&s->back, workBuffer, imageSize); |
| + free(workBuffer); |
| + workBuffer = NULL; |
| + |
| + } |
| + } |
| + |
| +} |
| + |
| + |
| +SANE_Status |
| +get_next_image(epsonds_scanner *s) |
| +{ |
| + SANE_Status status = SANE_STATUS_GOOD; |
| + |
| + if (s->acquirePage == 0 && s->current == &s->front) |
| + { |
| + DBG(20, "** %s: get_next_image\n", __func__); |
| + |
| + |
| + /*page info will be updatted by pen*/ |
| + s->width_back = 0; |
| + s->width_front = 0; |
| + s->height_back = 0; |
| + s->height_front = 0; |
| + |
| + if (s->mode_jpeg) |
| + { |
| + status = acquire_and_decode_jpeg_data(s); |
| + }else{ |
| + status = acquire_raw_data(s); |
| + } |
| + if (status != SANE_STATUS_GOOD) |
| + { |
| + eds_ring_flush(&s->front); |
| + eds_ring_flush(&s->back); |
| + eds_ring_destory(&s->front); |
| + eds_ring_destory(&s->back); |
| + } |
| + DBG(20," ringFront = %d ringBack = %d\n", eds_ring_avail(&s->front), eds_ring_avail(&s->back)); |
| + |
| + s->acquirePage = 1; |
| + } |
| + |
| + return status; |
| +} |
| + |
| + |
| SANE_Status |
| sane_get_parameters(SANE_Handle handle, SANE_Parameters *params) |
| { |
| @@ -1173,25 +2639,186 @@ sane_get_parameters(SANE_Handle handle, SANE_Parameters *params) |
| eds_init_parameters(s); |
| } |
| |
| + |
| + SANE_Status status = SANE_STATUS_GOOD; |
| + |
| + status = get_next_image(s); |
| + |
| + // if size auto, update page size value |
| + if(s->val[OPT_ADF_CRP].w) |
| + { |
| + // frontside |
| + if (s->current == &s->front) |
| + { |
| + DBG(20, "front side \n"); |
| + if (s->width_front != 0 && s->height_front != 0) |
| + { |
| + if (s->params.format == SANE_FRAME_RGB) |
| + { |
| + s->params.bytes_per_line = s->width_front * 3; |
| + s->params.pixels_per_line = s->width_front; |
| + } |
| + |
| + if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8) |
| + { |
| + s->params.bytes_per_line = s->width_front; |
| + s->params.pixels_per_line = s->width_front; |
| + } |
| + |
| + if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1) |
| + { |
| + s->params.bytes_per_line = (s->width_front + 7)/8; |
| + s->params.pixels_per_line = s->width_front; |
| + } |
| + s->params.lines = s->height_front; |
| + } |
| + } |
| + // backside |
| + if (s->current == &s->back) |
| + { |
| + DBG(20, "back side \n"); |
| + if (s->width_back != 0 && s->height_back != 0) |
| + { |
| + if (s->params.format == SANE_FRAME_RGB) |
| + { |
| + s->params.bytes_per_line = s->width_back * 3; |
| + s->params.pixels_per_line = s->width_back; |
| + } |
| + |
| + if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8) |
| + { |
| + s->params.bytes_per_line = s->width_back; |
| + s->params.pixels_per_line = s->width_back; |
| + } |
| + |
| + if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1) |
| + { |
| + s->params.bytes_per_line = (s->width_back + 7)/8; |
| + s->params.pixels_per_line = s->width_back; |
| + } |
| + s->params.lines = s->height_back; |
| + } |
| + } |
| + } |
| if (params != NULL) |
| *params = s->params; |
| |
| print_params(s->params); |
| |
| - return SANE_STATUS_GOOD; |
| + DBG(20, "s->params.line = %d s->params.bytes_per_line = %d s->params.pixels_per_line = %d \n", s->params.lines, s->params.bytes_per_line , s->params.pixels_per_line ); |
| + return status; |
| } |
| |
| + |
| + |
| +typedef float ColorMatrix[3][3]; |
| + |
| +#define CCT_TABLE_SIZE 9 |
| +static int get_roundup_index(double frac[], int n) |
| +{ |
| + int i, index = -1; |
| + double max_val = 0.0; |
| + |
| + for (i=0; i<n; i++) { |
| + if (frac[i]<0) continue; |
| + if (max_val<frac[i]) { |
| + index = i; |
| + max_val = frac[i]; |
| + } |
| + } |
| + return index; |
| +} |
| + |
| +static int get_rounddown_index(double frac[], int n) |
| +{ |
| + int i, index = -1; |
| + double min_val = 1.0; |
| + |
| + for (i=0; i<n; i++) { |
| + if (frac[i]>0) continue; |
| + if (min_val>frac[i]) { |
| + index = i; |
| + min_val = frac[i]; |
| + } |
| + } |
| + return index; |
| +} |
| + |
| + |
| +void ESCIRoundColorCorrectionMatrix(int mult, double org_cct[], int rnd_cct[]) |
| +{ |
| + int i, j, index; |
| + double mult_cct[CCT_TABLE_SIZE], frac[CCT_TABLE_SIZE]; |
| + int sum[3]; |
| + int loop; |
| + |
| + for (i=0; i<CCT_TABLE_SIZE; i++) { |
| + mult_cct[i] = org_cct[i] * mult; |
| + } |
| + |
| + // round value multiplied by 'mult' off to integer. |
| + for (i=0; i<CCT_TABLE_SIZE; i++) { |
| + rnd_cct[i] = (int)floor(org_cct[i] * mult + 0.5); |
| + } |
| + |
| + loop=0; |
| + do { |
| + // If all element equal to 11, diagonal element is set to 10. |
| + for (i=0; i<3; i++) { |
| + if ( (rnd_cct[i*3]==11) && |
| + (rnd_cct[i*3]==rnd_cct[i*3+1]) && |
| + (rnd_cct[i*3]==rnd_cct[i*3+2]) ) { |
| + rnd_cct[i*3+i] --; |
| + mult_cct[i*3+i] = rnd_cct[i*3+i]; |
| + } |
| + } |
| + // calc. summation of each line. |
| + for (i=0; i<3; i++) { |
| + sum[i] = 0; |
| + for (j=0; j<3; j++) { |
| + sum[i] += rnd_cct[i*3+j]; |
| + } |
| + } |
| + // calc. values rounded up or down. |
| + for (i=0; i<CCT_TABLE_SIZE; i++) { |
| + frac[i] = mult_cct[i] - rnd_cct[i]; |
| + } |
| + |
| + // if summation does not equal to 'mult', adjust rounded up or down value. |
| + for (i=0; i<3; i++) { |
| + if (sum[i]<mult) { |
| + index = get_roundup_index(&frac[i*3], 3); |
| + if (index!=-1) { |
| + rnd_cct[i*3+index] ++; |
| + mult_cct[i*3+index] = rnd_cct[i*3+index]; |
| + sum[i]++; |
| + } |
| + } else if (sum[i]>mult) { |
| + index = get_rounddown_index(&frac[i*3], 3); |
| + if (index!=-1) { |
| + rnd_cct[i*3+index] --; |
| + mult_cct[i*3+index] = rnd_cct[i*3+index]; |
| + sum[i]--; |
| + } |
| + } |
| + } |
| + |
| + } while ((++loop<2)&&((sum[0]!=mult)||(sum[1]!=mult)||(sum[2]!=mult))); |
| +} |
| + |
| + |
| + |
| /* |
| * This function is part of the SANE API and gets called from the front end to |
| * start the scan process. |
| */ |
| - |
| +#define CMD_BUF_SIZE 1000 |
| SANE_Status |
| sane_start(SANE_Handle handle) |
| { |
| epsonds_scanner *s = (epsonds_scanner *)handle; |
| char buf[65]; /* add one more byte to correct buffer overflow issue */ |
| - char cmd[100]; /* take care not to overflow */ |
| + char cmd[CMD_BUF_SIZE]; /* take care not to overflow */ |
| SANE_Status status = 0; |
| |
| s->pages++; |
| @@ -1203,26 +2830,28 @@ sane_start(SANE_Handle handle) |
| |
| s->eof = 0; |
| s->canceling = 0; |
| + s->acquirePage = 0; |
| |
| if ((s->pages % 2) == 1) { |
| s->current = &s->front; |
| - eds_ring_flush(s->current); |
| } else if (eds_ring_avail(&s->back)) { |
| DBG(5, "back side\n"); |
| s->current = &s->back; |
| } |
| |
| - /* prepare the JPEG decompressor */ |
| - if (s->mode_jpeg) { |
| - status = eds_jpeg_start(s); |
| - if (status != SANE_STATUS_GOOD) { |
| - goto end; |
| - } } |
| - |
| /* scan already in progress? (one pass adf) */ |
| - if (s->scanning) { |
| + if (s->scanning || eds_ring_avail(&s->back) > 0) { |
| DBG(5, " scan in progress, returning early\n"); |
| - return SANE_STATUS_GOOD; |
| + return get_next_image(s); |
| + } |
| + if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) { |
| + if (s->scanEnd) |
| + { |
| + s->scanEnd = 0; |
| + return SANE_STATUS_NO_DOCS; |
| + } |
| + }else{ |
| + s->scanEnd = 0; |
| } |
| |
| /* calc scanning parameters */ |
| @@ -1239,13 +2868,7 @@ sane_start(SANE_Handle handle) |
| |
| /* transfer buffer size, bsz */ |
| /* XXX read value from scanner */ |
| - s->bsz = (65536 * 4); |
| - |
| - /* ring buffer for front page */ |
| - status = eds_ring_init(&s->front, s->bsz * 2); |
| - if (status != SANE_STATUS_GOOD) { |
| - return status; |
| - } |
| + s->bsz = (1048576 * 4); |
| |
| /* transfer buffer */ |
| s->buf = realloc(s->buf, s->bsz); |
| @@ -1256,29 +2879,34 @@ sane_start(SANE_Handle handle) |
| |
| /* set scanning parameters */ |
| |
| + s->isDuplexScan = 0; |
| /* document source */ |
| - if (strcmp(source_list[s->val[OPT_SOURCE].w], ADF_STR) == 0) { |
| + if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) { |
| |
| - sprintf(buf, "#ADF%s%s", |
| - s->val[OPT_ADF_MODE].w ? "DPLX" : "", |
| - s->val[OPT_ADF_SKEW].w ? "SKEW" : ""); |
| - |
| - /* it seems that DFL only works in duplex mode, but it's |
| - * also required to be enabled or duplex will be rejected. |
| - */ |
| - |
| - if (s->val[OPT_ADF_MODE].w) { |
| - |
| - if (s->hw->adf_has_dfd == 2) { |
| - strcat(buf, "DFL2"); |
| - } else if (s->hw->adf_has_dfd == 1) { |
| - strcat(buf, "DFL1"); |
| - } |
| + SANE_Int status = esci2_stat(s); |
| + if (status == SANE_STATUS_NO_DOCS) |
| + { |
| + return SANE_STATUS_NO_DOCS; |
| } |
| |
| - } else if (strcmp(source_list[s->val[OPT_SOURCE].w], FBF_STR) == 0) { |
| + SANE_Int duplexMode = (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0); |
| + |
| + sprintf(buf, "#ADF%s%s%s", |
| + duplexMode ? "DPLX" : "", |
| + s->val[OPT_ADF_SKEW].w ? "SKEW" : "", |
| + s->val[OPT_ADF_CRP].w ? "CRP " : "" |
| + ); |
| + |
| + if (duplexMode) |
| + { |
| + s->isDuplexScan = 1; |
| + } |
| + s->isflatbedScan = 0; |
| + } |
| + else if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_FLATBED) == 0) { |
| |
| strcpy(buf, "#FB "); |
| + s->isflatbedScan = 1; |
| |
| } else { |
| /* XXX */ |
| @@ -1286,8 +2914,18 @@ sane_start(SANE_Handle handle) |
| |
| strcpy(cmd, buf); |
| |
| + s->needToConvertBW = 0; |
| + |
| if (s->params.format == SANE_FRAME_GRAY) { |
| - sprintf(buf, "#COLM%03d", s->params.depth); |
| + if (s->params.depth == 1 && s->hw->has_mono == 0) |
| + { |
| + sprintf(buf, "#COLM008"); |
| + s->needToConvertBW = 1; |
| + s->mode_jpeg = 1; |
| + }else |
| + { |
| + sprintf(buf, "#COLM%03d", s->params.depth); |
| + } |
| } else if (s->params.format == SANE_FRAME_RGB) { |
| sprintf(buf, "#COLC%03d", s->params.depth * 3); |
| } |
| @@ -1303,9 +2941,29 @@ sane_start(SANE_Handle handle) |
| strcat(cmd, "#FMTJPG #JPGd090"); |
| } |
| |
| + /* set GMM */ |
| + if (s->params.depth == 1) |
| + { |
| + sprintf(buf, "#GMMUG10"); |
| + } else |
| + { |
| + sprintf(buf, "#GMMUG18"); |
| + } |
| + strcat(cmd, buf); |
| + |
| /* resolution (RSMi not always supported) */ |
| |
| - if (s->val[OPT_RESOLUTION].w > 999) { |
| + if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 && s->val[OPT_RESOLUTION].w > 600) { |
| + DBG(0, "Automatic Document Feeder supported resolution of 600dpi or less. \n"); |
| + } else if (s->val[OPT_RESOLUTION].w > 999) { |
| + sprintf(buf, "#RSMi%07d#RSSi%07d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w); |
| + } else { |
| + sprintf(buf, "#RSMd%03d#RSSd%03d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w); |
| + } |
| + |
| + if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0 && s->val[OPT_RESOLUTION].w > 600) { |
| + DBG(0, "Automatic Document Feeder supported resolution of 600dpi or less. \n"); |
| + } else if (s->val[OPT_RESOLUTION].w > 999) { |
| sprintf(buf, "#RSMi%07d#RSSi%07d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w); |
| } else { |
| sprintf(buf, "#RSMd%03d#RSSd%03d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w); |
| @@ -1313,13 +2971,321 @@ sane_start(SANE_Handle handle) |
| |
| strcat(cmd, buf); |
| |
| + if (strcmp(s->hw->sane.model, (char*)"DS-70") == 0 || strcmp(s->hw->sane.model, (char*)"ES-65WR") == 0 || strcmp(s->hw->sane.model, (char*)"ES-60W") == 0 |
| + || strcmp(s->hw->sane.model, (char*)"DS-80W") == 0 || strcmp(s->hw->sane.model, (char*)"ES-55R") == 0 || strcmp(s->hw->sane.model, (char*)"ES-50") == 0){ |
| + sprintf(buf, "#BSZi0262144"); |
| + strcat(cmd, buf); |
| + } |
| + else { |
| + sprintf(buf, "#BSZi1048576"); |
| + strcat(cmd, buf); |
| + } |
| + |
| + |
| /* scanning area */ |
| + |
| sprintf(buf, "#ACQi%07di%07di%07di%07d", |
| s->left, s->top, s->params.pixels_per_line, s->params.lines); |
| |
| + |
| + if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) { |
| + status = esci2_stat(s); |
| + if (status != SANE_STATUS_GOOD) { |
| + goto end; |
| + } |
| + } |
| + |
| strcat(cmd, buf); |
| |
| - status = esci2_para(s, cmd); |
| + |
| + int pos = 0; |
| + |
| + { |
| + for (int i = 0; i < CMD_BUF_SIZE; i++) |
| + { |
| + // find end of string |
| + if(cmd[i] == 0) |
| + { |
| + pos = i; |
| + break; |
| + } |
| + } |
| + |
| + |
| + if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8) { |
| + DBG(10, "SANE_FRAME_GRAY\n"); |
| + cmd[pos++] = '#'; |
| + cmd[pos++] = 'G'; |
| + cmd[pos++] = 'M'; |
| + cmd[pos++] = 'T'; |
| + cmd[pos++] = 'M'; |
| + cmd[pos++] = 'O'; |
| + cmd[pos++] = 'N'; |
| + cmd[pos++] = 'O'; |
| + cmd[pos++] = 'h'; |
| + cmd[pos++] = '1'; |
| + cmd[pos++] = '0'; |
| + cmd[pos++] = '0'; |
| + |
| + for(int count = 0; count < 256; count++) { |
| + cmd[pos++] = LUT[s->hw->lut_id][count]; |
| + } |
| + } |
| + if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1) { |
| + DBG(10, "SANE_FRAME_GRAY\n"); |
| + cmd[pos++] = '#'; |
| + cmd[pos++] = 'G'; |
| + cmd[pos++] = 'M'; |
| + cmd[pos++] = 'T'; |
| + cmd[pos++] = 'M'; |
| + cmd[pos++] = 'O'; |
| + cmd[pos++] = 'N'; |
| + cmd[pos++] = 'O'; |
| + cmd[pos++] = 'h'; |
| + cmd[pos++] = '1'; |
| + cmd[pos++] = '0'; |
| + cmd[pos++] = '0'; |
| + |
| + for(int count = 0; count < 256; count++) { |
| + cmd[pos++] = LUT[0][count]; |
| + } |
| + } |
| + else if (s->params.format == SANE_FRAME_RGB) { |
| + DBG(10, "SANE_FRAME_RGB\n"); |
| + cmd[pos++] = '#'; |
| + cmd[pos++] = 'G'; |
| + cmd[pos++] = 'M'; |
| + cmd[pos++] = 'T'; |
| + cmd[pos++] = 'R'; |
| + cmd[pos++] = 'E'; |
| + cmd[pos++] = 'D'; |
| + cmd[pos++] = ' '; |
| + cmd[pos++] = 'h'; |
| + cmd[pos++] = '1'; |
| + cmd[pos++] = '0'; |
| + cmd[pos++] = '0'; |
| + |
| + for(int count = 0; count < 256; count++) { |
| + cmd[pos++] = LUT_R[s->hw->lut_id][count]; |
| + } |
| + |
| + cmd[pos++] = '#'; |
| + cmd[pos++] = 'G'; |
| + cmd[pos++] = 'M'; |
| + cmd[pos++] = 'T'; |
| + cmd[pos++] = 'G'; |
| + cmd[pos++] = 'R'; |
| + cmd[pos++] = 'N'; |
| + cmd[pos++] = ' '; |
| + cmd[pos++] = 'h'; |
| + cmd[pos++] = '1'; |
| + cmd[pos++] = '0'; |
| + cmd[pos++] = '0'; |
| + |
| + for(int count = 0; count < 256; count++) { |
| + cmd[pos++] = LUT_G[s->hw->lut_id][count]; |
| + } |
| + |
| + cmd[pos++] = '#'; |
| + cmd[pos++] = 'G'; |
| + cmd[pos++] = 'M'; |
| + cmd[pos++] = 'T'; |
| + cmd[pos++] = 'B'; |
| + cmd[pos++] = 'L'; |
| + cmd[pos++] = 'U'; |
| + cmd[pos++] = ' '; |
| + cmd[pos++] = 'h'; |
| + cmd[pos++] = '1'; |
| + cmd[pos++] = '0'; |
| + cmd[pos++] = '0'; |
| + |
| + for(int count = 0; count < 256; count++) { |
| + cmd[pos++] = LUT_B[s->hw->lut_id][count]; |
| + } |
| + } |
| + cmd[pos] = 0; |
| + |
| + } |
| + {// Set Color Matrix |
| + if (s->params.format == SANE_FRAME_RGB && s->hw->lut_id != 0 )/*Color Matrix Target devide and color Scan*/ |
| + { |
| + ColorMatrix matrix; |
| + |
| + // DS-530 |
| + |
| + if (s->hw->lut_id == 2) |
| + { |
| + // R |
| + matrix[0][0] = 1.0229; |
| + matrix[0][1] = 0.0009; |
| + matrix[0][2] = -0.0238; |
| + |
| + // G |
| + matrix[1][0] = 0.0031; |
| + matrix[1][1] = 1.0287; |
| + matrix[1][2] = -0.0318; |
| + |
| + //B |
| + matrix[2][0] = 0.0044; |
| + matrix[2][1] = -0.1150; |
| + matrix[2][2] = 1.1106; |
| + } |
| + |
| + // DS-1660W Flatbed |
| + |
| + if (s->hw->lut_id == 4) |
| + { |
| + // R |
| + matrix[0][0] = 1.0229; |
| + matrix[0][1] = 0.0009; |
| + matrix[0][2] = -0.0238; |
| + |
| + // G |
| + matrix[1][0] = 0.0031; |
| + matrix[1][1] = 1.0287; |
| + matrix[1][2] = -0.0318; |
| + |
| + //B |
| + matrix[2][0] = 0.0044; |
| + matrix[2][1] = -0.1150; |
| + matrix[2][2] = 1.1106; |
| + } |
| + |
| + |
| + // DS-320 |
| + |
| + if (s->hw->lut_id == 5) |
| + { |
| + // R |
| + matrix[0][0] = 1.0250; |
| + matrix[0][1] = 0.0004; |
| + matrix[0][2] = -0.0254; |
| + |
| + // G |
| + matrix[1][0] = 0.0003; |
| + matrix[1][1] = 1.0022; |
| + matrix[1][2] = -0.0025; |
| + |
| + //B |
| + matrix[2][0] = 0.0049; |
| + matrix[2][1] = -0.0949; |
| + matrix[2][2] = 1.0900; |
| + } |
| + |
| + |
| + // ES-50 |
| + |
| + if (s->hw->lut_id == 6) |
| + { |
| + // R |
| + matrix[0][0] = 1.0383; |
| + matrix[0][1] = -0.0021; |
| + matrix[0][2] = -0.0362; |
| + |
| + // G |
| + matrix[1][0] = 0.0046; |
| + matrix[1][1] = 1.0576; |
| + matrix[1][2] = -0.0622; |
| + |
| + //B |
| + matrix[2][0] = 0.0235; |
| + matrix[2][1] = -0.2396; |
| + matrix[2][2] = 1.2161; |
| + } |
| + |
| + |
| + // R |
| + matrix[0][0] = 0.9864; |
| + matrix[0][1] = 0.0248; |
| + matrix[0][2] = -0.0112; |
| + |
| + // G |
| + matrix[1][0] = 0.0021; |
| + matrix[1][1] = 1.0100; |
| + matrix[1][2] = -0.0112; |
| + |
| + //B |
| + matrix[2][0] = 0.0139; |
| + matrix[2][1] = -0.1249; |
| + matrix[2][2] = 1.1110; |
| + |
| + |
| + // Set Matrix value |
| + { |
| + cmd[pos++] = '#'; |
| + cmd[pos++] = 'C'; |
| + cmd[pos++] = 'M'; |
| + cmd[pos++] = 'X'; |
| + cmd[pos++] = 'U'; |
| + cmd[pos++] = 'M'; |
| + cmd[pos++] = '0'; |
| + cmd[pos++] = '8'; |
| + cmd[pos++] = 'h'; |
| + cmd[pos++] = '0'; |
| + cmd[pos++] = '0'; |
| + cmd[pos++] = '9'; |
| + } |
| + |
| + |
| + // Matrix to be sent to scanner must be following d1-d9 order: |
| + // |
| + // G R B |
| + // G [d1 d4 d7] |
| + // R [d2 d5 d8] |
| + // B [d3 d6 d9] |
| + // |
| + // So, we will convert it with index table. |
| + char index[9] = {4, 1, 7, 3, 0, 6, 5, 2, 8}; |
| + |
| + double flatten[9] = {0}; |
| + for (int row = 0; row < 3; row++) { |
| + for (int col = 0; col < 3; col++) { |
| + flatten[row * 3 + col] = matrix[row][col]; |
| + } |
| + } |
| + |
| + int rounded[9] = {0}; |
| + ESCIRoundColorCorrectionMatrix(32, flatten, rounded); |
| + |
| + |
| + char ordered[9] = {0}; |
| + for (int row = 0; row < 3; row++) { |
| + for (int col = 0; col < 3; col++) { |
| + int val = rounded[row * 3 + col]; |
| + unsigned char oct = (unsigned char)abs(val); |
| + oct |= ((val < 0) ? (1 << 7) : 0); |
| + ordered[(signed char)index[row * 3 + col]] = oct; |
| + } |
| + } |
| + { |
| + cmd[pos++] = ordered[0]; |
| + cmd[pos++] = ordered[1]; |
| + cmd[pos++] = ordered[2]; |
| + cmd[pos++] = ordered[3]; |
| + cmd[pos++] = ordered[4]; |
| + cmd[pos++] = ordered[5]; |
| + cmd[pos++] = ordered[6]; |
| + cmd[pos++] = ordered[7]; |
| + cmd[pos++] = ordered[8]; |
| + cmd[pos++] = 0; //padding |
| + cmd[pos++] = 0; //padding |
| + cmd[pos++] = 0; //padding |
| + |
| + |
| + DBG(1, "color matrix\n"); |
| + for (int i = 0; i < 9; i++) |
| + { |
| + DBG(1, "%d\n", ordered[i]); |
| + } |
| + |
| + } |
| + cmd[pos] = 0; |
| + } |
| + |
| + } |
| + |
| + |
| + status = esci2_para(s, cmd, pos); |
| if (status != SANE_STATUS_GOOD) { |
| goto end; |
| } |
| @@ -1336,7 +3302,8 @@ sane_start(SANE_Handle handle) |
| /* first page is page 1 */ |
| s->pages = 1; |
| s->scanning = 1; |
| - |
| + s->dummy = 0; |
| + s->scanEnd = 0; |
| end: |
| if (status != SANE_STATUS_GOOD) { |
| DBG(1, "%s: start failed: %s\n", __func__, sane_strstatus(status)); |
| @@ -1345,140 +3312,305 @@ end: |
| return status; |
| } |
| |
| -/* this moves data from our buffers to SANE */ |
| - |
| -SANE_Status |
| -sane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length, |
| - SANE_Int *length) |
| +static SANE_Status acquire_jpeg_data(epsonds_scanner* s) |
| { |
| - SANE_Int read = 0, tries = 3; |
| - SANE_Int available; |
| - SANE_Status status = 0; |
| - epsonds_scanner *s = (epsonds_scanner *)handle; |
| |
| - *length = read = 0; |
| + SANE_Int read = 0; |
| |
| - DBG(20, "** %s: backside = %d\n", __func__, s->backside); |
| - |
| - /* sane_read called before sane_start? */ |
| - if (s->current == NULL) { |
| - DBG(0, "%s: buffer is NULL", __func__); |
| - return SANE_STATUS_INVAL; |
| + SANE_Int jpegBufSize = s->params.bytes_per_line * s->params.lines; |
| + if (s->needToConvertBW) |
| + { |
| + jpegBufSize = s->params.pixels_per_line * s->params.lines; |
| } |
| |
| + |
| + s->frontJpegBuf = malloc(jpegBufSize); |
| + s->backJpegBuf = malloc(jpegBufSize); |
| + s->frontJpegBufLen = 0; |
| + s->backJpegBufLen = 0; |
| + |
| + // load all images, decode and fill buffer |
| + SANE_Int status = SANE_STATUS_GOOD; |
| + |
| + int eofFront = 0; |
| + int eofBack = 0; |
| + |
| + |
| + status = eds_ring_init(&s->front, (s->params.bytes_per_line) * s->params.lines); |
| + if (status != SANE_STATUS_GOOD) { |
| + return status; |
| + } |
| + |
| + status = eds_ring_init(&s->back, (s->params.bytes_per_line) * s->params.lines); |
| + if (status != SANE_STATUS_GOOD) { |
| + return status; |
| + } |
| + |
| + while (1) |
| + { |
| + status = esci2_img(s, &read); |
| + DBG(20, "acquire_jpeg_data read: %d, eof: %d, backside: %d, status: %d\n", read, s->eof, s->backside, status); |
| + if (read) |
| + { |
| + if (s->backside) |
| + { |
| + SANE_Byte* backBuffer = s->backJpegBuf + s->backJpegBufLen; |
| + memcpy(backBuffer, s->buf, read); |
| + s->backJpegBufLen += read; |
| + }else{ |
| + SANE_Byte* frontBuffer = s->frontJpegBuf + s->frontJpegBufLen ; |
| + memcpy(frontBuffer, s->buf, read); |
| + s->frontJpegBufLen += read; |
| + } |
| + } |
| + if (status == SANE_STATUS_GOOD) |
| + { |
| + |
| + DBG(20, "continue acquire image\n"); |
| + continue; |
| + } |
| + else if (status == SANE_STATUS_EOF) |
| + { |
| + if (s->backside) |
| + { |
| + DBG(20, "eofBack\n"); |
| + eofBack = 1; |
| + }else{ |
| + DBG(20, "eofFront\n"); |
| + eofFront = 1; |
| + } |
| + }else if (status == SANE_STATUS_CANCELLED) |
| + { |
| + // cancel cleanup |
| + esci2_can(s); |
| + |
| + free(s->frontJpegBuf); |
| + free(s->backJpegBuf); |
| + s->frontJpegBuf = NULL; |
| + s->backJpegBuf = NULL; |
| + return status; |
| + }else{ |
| + // error occurs cleanup |
| + free(s->frontJpegBuf); |
| + free(s->backJpegBuf); |
| + s->frontJpegBuf = NULL; |
| + s->backJpegBuf = NULL; |
| + return status; |
| + } |
| + |
| + |
| + if (s->isDuplexScan) |
| + { |
| + DBG(20, "eofFront = %d eofBack = %d\n", eofFront, eofBack); |
| + // acquire finish |
| + if (eofFront && eofBack) |
| + { |
| + DBG(20, "eofFront && eofBack end\n"); |
| + break; |
| + } |
| + }else{ |
| + if (eofFront) |
| + { |
| + DBG(20, "eofFront end\n"); |
| + break; |
| + } |
| + } |
| + } |
| + |
| + return SANE_STATUS_GOOD; |
| +} |
| + |
| +static SANE_Status |
| +acquire_raw_data(epsonds_scanner* s) |
| +{ |
| + SANE_Int read = 0; |
| + |
| + // load all images, decode and fill buffer |
| + SANE_Int status = SANE_STATUS_GOOD; |
| + |
| + int eofFront = 0; |
| + int eofBack = 0; |
| + int firstWrite = 1; |
| + |
| + while (1) |
| + { |
| + DBG(20, "acquire_raw_data loop start\n"); |
| + status = esci2_img(s, &read); |
| + DBG(20, "acquire_raw_data read: %d, eof: %d, backside: %d, status: %d\n", read, s->eof, s->backside, status); |
| + |
| + if (read) |
| + { |
| + if (firstWrite) |
| + { |
| + status = eds_ring_init(&s->front, (s->params.bytes_per_line + s->dummy) * s->params.lines); |
| + if (status != SANE_STATUS_GOOD) { |
| + return status; |
| + } |
| + |
| + status = eds_ring_init(&s->back, (s->params.bytes_per_line + s->dummy) * s->params.lines); |
| + if (status != SANE_STATUS_GOOD) { |
| + return status; |
| + } |
| + firstWrite = 0; |
| + } |
| + |
| + DBG(20, "eds_ring_write start\n"); |
| + status = eds_ring_write(s->backside ? &s->back : &s->front, s->buf, read); |
| + DBG(20, "eds_ring_write end\n"); |
| + } |
| + DBG(20, "acquire_raw_data3\n"); |
| + |
| + if (status == SANE_STATUS_GOOD) |
| + { |
| + DBG(20, "contiune acquire image\n"); |
| + continue; |
| + } |
| + else if (status == SANE_STATUS_EOF) |
| + { |
| + if (s->backside) |
| + { |
| + eofBack = 1; |
| + }else{ |
| + eofFront = 1; |
| + } |
| + } |
| + else if (status == SANE_STATUS_CANCELLED) |
| + { |
| + esci2_can(s); |
| + return status; |
| + }else{ |
| + // error occurs cleanup |
| + return status; |
| + } |
| + |
| + if (s->isDuplexScan) |
| + { |
| + // acquire finish |
| + if (eofFront && eofBack) |
| + { |
| + break; |
| + } |
| + }else{ |
| + if (eofFront) |
| + { |
| + break; |
| + } |
| + } |
| + } |
| + |
| + |
| + int needBytes = (s->params.bytes_per_line + s->dummy) * s->params.lines; |
| + { |
| + int available = eds_ring_avail(&s->front); |
| + if (available < needBytes) |
| + { |
| + int required = needBytes - available; |
| + unsigned char* padding = (unsigned char*)malloc(required); |
| + memset(padding, 255, required); |
| + eds_ring_write(&s->front, padding, required); |
| + free(padding); |
| + |
| + } |
| + |
| + } |
| + { |
| + int available = eds_ring_avail(&s->back); |
| + if (available > 0 && available < needBytes) |
| + { |
| + int required = needBytes - available; |
| + unsigned char* padding = (unsigned char*)malloc(required); |
| + memset(padding, 255, required); |
| + eds_ring_write(&s->back, padding, required); |
| + free(padding); |
| + } |
| + |
| + } |
| + |
| + if (s->isDuplexScan) |
| + { |
| + upside_down_backside_image(s); |
| + } |
| + |
| + DBG(20, "acquire_raw_data finish"); |
| + return SANE_STATUS_GOOD; |
| + |
| +} |
| + |
| +static SANE_Status |
| +acquire_and_decode_jpeg_data(epsonds_scanner* s) |
| +{ |
| + SANE_Int status = acquire_jpeg_data(s); |
| + if (status == SANE_STATUS_GOOD) |
| + { |
| + DBG(20, "** %s: sane status = %d needToConvertBW = %d \n", __func__, status, s->needToConvertBW); |
| + |
| + // process front page |
| + if (s->frontJpegBufLen > 0) |
| + { |
| + eds_decode_jpeg(s, s->frontJpegBuf, s->frontJpegBufLen, &s->front,0, s->needToConvertBW); |
| + free(s->frontJpegBuf); |
| + s->frontJpegBuf = NULL; |
| + } |
| + // process back page |
| + if (s->backJpegBufLen > 0) |
| + { |
| + eds_decode_jpeg(s, s->backJpegBuf, s->backJpegBufLen, &s->back, 1, s->needToConvertBW); |
| + free(s->backJpegBuf); |
| + s->backJpegBuf = NULL; |
| + } |
| + |
| + if (s->isDuplexScan) |
| + { |
| + upside_down_backside_image(s); |
| + } |
| + }else{ |
| + DBG(20, "** %s: sane finish status = %d\n", __func__, status); |
| + return status; |
| + } |
| + return status; |
| +} |
| + |
| +int sumLength = 0; |
| +/* this moves data from our buffers to SANE */ |
| +SANE_Status |
| +sane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length, SANE_Int *length) |
| +{ |
| + epsonds_scanner *s = (epsonds_scanner *)handle; |
| + SANE_Int read = 0; |
| + |
| + if (s->canceling) |
| + { |
| + esci2_can(s); |
| + *length = 0; |
| + return SANE_STATUS_CANCELLED; |
| + } |
| + |
| + int available = eds_ring_avail(s->current); |
| /* anything in the buffer? pass it to the frontend */ |
| - available = eds_ring_avail(s->current); |
| - if (available) { |
| + if (available > 0) { |
| |
| DBG(18, "reading from ring buffer, %d left\n", available); |
| |
| - if (s->mode_jpeg && !s->jpeg_header_seen) { |
| - |
| - status = eds_jpeg_read_header(s); |
| - if (status != SANE_STATUS_GOOD && --tries) { |
| - goto read_again; |
| - } |
| - } |
| - |
| - if (s->mode_jpeg) { |
| - eds_jpeg_read(handle, data, max_length, &read); |
| - } else { |
| - eds_copy_image_from_ring(s, data, max_length, &read); |
| - } |
| + eds_copy_image_from_ring(s, data, max_length, &read); |
| |
| + // data is empty fin |
| if (read == 0) { |
| - goto read_again; |
| + *length = 0; |
| + eds_ring_flush(s->current); |
| + eds_ring_destory(s->current); |
| + DBG(18, "returns EOF 2\n"); |
| + return SANE_STATUS_EOF; |
| } |
| - |
| *length = read; |
| |
| return SANE_STATUS_GOOD; |
| - |
| - |
| - } else if (s->current == &s->back) { |
| - |
| - /* finished reading the back page, next |
| - * command should give us the EOF |
| - */ |
| - DBG(18, "back side ring buffer empty\n"); |
| + }else{ |
| + *length = 0; |
| + eds_ring_flush(s->current); |
| + eds_ring_destory(s->current); |
| + DBG(18, "returns EOF 1\n"); |
| + return SANE_STATUS_EOF; |
| } |
| - |
| - /* read until data or error */ |
| - |
| -read_again: |
| - |
| - status = esci2_img(s, &read); |
| - if (status != SANE_STATUS_GOOD) { |
| - DBG(20, "read: %d, eof: %d, backside: %d, status: %d\n", read, s->eof, s->backside, status); |
| - } |
| - |
| - /* just got a back side page, alloc ring buffer if necessary |
| - * we didn't before because dummy was not known |
| - */ |
| - if (s->backside) { |
| - |
| - int required = s->params.lines * (s->params.bytes_per_line + s->dummy); |
| - |
| - if (s->back.size < required) { |
| - |
| - DBG(20, "allocating buffer for the back side\n"); |
| - |
| - status = eds_ring_init(&s->back, required); |
| - if (status != SANE_STATUS_GOOD) { |
| - return status; |
| - } |
| - } |
| - } |
| - |
| - /* abort scanning when appropriate */ |
| - if (status == SANE_STATUS_CANCELLED) { |
| - esci2_can(s); |
| - return status; |
| - } |
| - |
| - if (s->eof && s->backside) { |
| - DBG(18, "back side scan finished\n"); |
| - } |
| - |
| - /* read again if no error and no data */ |
| - if (read == 0 && status == SANE_STATUS_GOOD) { |
| - goto read_again; |
| - } |
| - |
| - /* got something, write to ring */ |
| - if (read) { |
| - |
| - DBG(20, " %d bytes read, %d lines, eof: %d, canceling: %d, status: %d, backside: %d\n", |
| - read, read / (s->params.bytes_per_line + s->dummy), |
| - s->canceling, s->eof, status, s->backside); |
| - |
| - /* move data to the appropriate ring */ |
| - status = eds_ring_write(s->backside ? &s->back : &s->front, s->buf, read); |
| - |
| - if (0 && s->mode_jpeg && !s->jpeg_header_seen |
| - && status == SANE_STATUS_GOOD) { |
| - |
| - status = eds_jpeg_read_header(s); |
| - if (status != SANE_STATUS_GOOD && --tries) { |
| - goto read_again; |
| - } |
| - } |
| - } |
| - |
| - /* continue reading if appropriate */ |
| - if (status == SANE_STATUS_GOOD) |
| - return status; |
| - |
| - /* cleanup */ |
| - DBG(5, "** %s: cleaning up\n", __func__); |
| - |
| - if (s->mode_jpeg) { |
| - eds_jpeg_finish(s); |
| - } |
| - |
| - eds_ring_flush(s->current); |
| - |
| - return status; |
| } |
| |
| /* |
| diff --git a/backend/epsonds.conf.in b/backend/epsonds.conf.in |
| index 1967a00fd..e2880fa21 100644 |
| --- a/backend/epsonds.conf.in |
| +++ b/backend/epsonds.conf.in |
| @@ -10,7 +10,8 @@ usb |
| # e.g.: |
| # usb 0x4b8 0x14c |
| |
| -# Network (not yet supported!) |
| +# |
| +# Network |
| # |
| # net 192.168.1.123 |
| -#net autodiscovery |
| +net autodiscovery |
| diff --git a/backend/epsonds.h b/backend/epsonds.h |
| index 04cb7244d..7f1b6509b 100644 |
| --- a/backend/epsonds.h |
| +++ b/backend/epsonds.h |
| @@ -66,9 +66,14 @@ |
| #define TPU_STR SANE_I18N("Transparency Unit") |
| #define ADF_STR SANE_I18N("Automatic Document Feeder") |
| |
| +#define STRING_FLATBED SANE_I18N("Flatbed") |
| +#define STRING_ADFFRONT SANE_I18N("ADF Front") |
| +#define STRING_ADFDUPLEX SANE_I18N("ADF Duplex") |
| + |
| enum { |
| OPT_NUM_OPTS = 0, |
| - OPT_MODE_GROUP, |
| + OPT_STANDARD_GROUP, |
| + OPT_SOURCE, |
| OPT_MODE, |
| OPT_DEPTH, |
| OPT_RESOLUTION, |
| @@ -78,11 +83,10 @@ enum { |
| OPT_BR_X, |
| OPT_BR_Y, |
| OPT_EQU_GROUP, |
| - OPT_SOURCE, |
| OPT_EJECT, |
| OPT_LOAD, |
| - OPT_ADF_MODE, |
| OPT_ADF_SKEW, |
| + OPT_ADF_CRP, |
| NUM_OPTIONS |
| }; |
| |
| @@ -119,6 +123,8 @@ struct epsonds_device |
| |
| SANE_Bool has_raw; /* supports RAW format */ |
| |
| + SANE_Bool has_mono; /*supprt M001*/ |
| + |
| SANE_Bool has_fb; /* flatbed */ |
| SANE_Range fbf_x_range; /* x range */ |
| SANE_Range fbf_y_range; /* y range */ |
| @@ -136,9 +142,13 @@ struct epsonds_device |
| SANE_Byte adf_alignment; /* left, center, right */ |
| SANE_Byte adf_has_dfd; /* supports double feed detection */ |
| |
| + SANE_Byte adf_has_crp; /* supports crp */ |
| + |
| SANE_Bool has_tpu; /* tpu */ |
| SANE_Range tpu_x_range; /* transparency unit x range */ |
| SANE_Range tpu_y_range; /* transparency unit y range */ |
| + |
| + SANE_Int lut_id; |
| }; |
| |
| typedef struct epsonds_device epsonds_device; |
| @@ -171,6 +181,10 @@ struct epsonds_scanner |
| |
| SANE_Int left, top, pages, dummy; |
| |
| + SANE_Int width_front, height_front; |
| + SANE_Int width_back , height_back; |
| + SANE_Int width_temp, height_temp; |
| + |
| /* jpeg stuff */ |
| |
| djpeg_dest_ptr jdst; |
| @@ -181,7 +195,18 @@ struct epsonds_scanner |
| /* network buffers */ |
| unsigned char *netbuf, *netptr; |
| size_t netlen; |
| -}; |
| + |
| + SANE_Byte *frontJpegBuf, *backJpegBuf; |
| + SANE_Int frontJpegBufLen, backJpegBufLen; |
| + SANE_Int acquirePage; |
| + |
| + SANE_Int isflatbedScan; |
| + SANE_Int isDuplexScan; |
| + |
| + SANE_Int needToConvertBW; |
| + |
| + SANE_Int scanEnd; |
| + }; |
| |
| typedef struct epsonds_scanner epsonds_scanner; |
| |
| diff --git a/doc/descriptions/epsonds.desc b/doc/descriptions/epsonds.desc |
| index 37d0e7635..2e79a118f 100644 |
| --- a/doc/descriptions/epsonds.desc |
| +++ b/doc/descriptions/epsonds.desc |
| @@ -93,3 +93,253 @@ |
| :interface "USB" |
| :usbid "0x04b8" "0x08cc" |
| :status :untested |
| + |
| +:model "DS-410" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0165" |
| +:status :complete |
| + |
| +:model "ES-50" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x016c" |
| +:status :complete |
| + |
| +:model "DS-70" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0160" |
| +:status :complete |
| + |
| +:model "ES-55R" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x016d" |
| +:status :complete |
| + |
| +:model "RR-60" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x018c" |
| +:status :complete |
| + |
| +:model "ES-60W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x016e" |
| +:status :complete |
| + |
| +:model "DS-80W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0166" |
| +:status :complete |
| + |
| +:model "ES-65WR" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x016f" |
| +:status :complete |
| + |
| +:model "RR-70W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x018b" |
| +:status :complete |
| + |
| +:model "ES-60WW" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x016e" |
| +:status :complete |
| + |
| +:model "ES-60WB" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x016e" |
| +:status :complete |
| + |
| +:model "DS-1630" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x015c" |
| +:status :complete |
| + |
| +:model "DS-1610" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x015d" |
| +:status :complete |
| + |
| +:model "DS-1660W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x015e" |
| +:status :complete |
| + |
| +:model "DS-310" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0159" |
| +:status :complete |
| + |
| +:model "ES-200" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0159" |
| +:status :complete |
| + |
| +:model "DS-320" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0162" |
| +:status :complete |
| + |
| +:model "DS-360W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x015a" |
| +:status :complete |
| + |
| +:model "ES-300W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x015a" |
| +:status :complete |
| + |
| +:model "ES-300WR" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0177" |
| +:status :complete |
| + |
| +:model "ES-400II" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0181" |
| +:status :complete |
| + |
| +:model "DS-535II" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0183" |
| +:status :complete |
| + |
| +:model "DS-531" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0184" |
| +:status :complete |
| + |
| +:model "DS-530II" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0182" |
| +:status :complete |
| + |
| +:model "ES-500WII" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0185" |
| +:status :complete |
| + |
| +:model "DS-571W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0188" |
| +:status :complete |
| + |
| +:model "DS-575WII" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0187" |
| +:status :complete |
| + |
| +:model "DS-570WII" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0186" |
| +:status :complete |
| + |
| +:model "ES-580W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x017f" |
| +:status :complete |
| + |
| +:model "RR-600W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0180" |
| +:status :complete |
| + |
| +:model "DS-535" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0167" |
| +:status :complete |
| + |
| +:model "DS-535H" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x017a" |
| +:status :complete |
| + |
| +:model "ES-400" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0156" |
| +:status :complete |
| + |
| +:model "DS-530" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0155" |
| +:status :complete |
| + |
| +:model "FF-680W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x016b" |
| +:status :complete |
| + |
| +:model "DS-570W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0157" |
| +:status :complete |
| + |
| +:model "ES-500W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0157" |
| +:status :complete |
| + |
| +:model "DS-575W" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0169" |
| +:status :complete |
| + |
| +:model "ES-500WR" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x0176" |
| +:status :complete |
| + |
| +:model "EW-052A Series" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x114e" |
| +:status :complete |
| + |
| +:model "XP-2100 Series" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x114e" |
| +:status :complete |
| + |
| +:model "ET-2700 Series" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x1135" |
| +:status :complete |
| + |
| +:model "L4150 Series" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x1135" |
| +:status :complete |
| + |
| +:model "ET-M2140 Series" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x114a" |
| +:status :complete |
| + |
| +:model "M2140 Series" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x114a" |
| +:status :complete |
| + |
| +:model "ET-M3140 Series" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x114f" |
| +:status :complete |
| + |
| +:model "M3140 Series" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x114f" |
| +:status :complete |
| + |
| +:model "L3150 Series" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x1143" |
| +:status :complete |
| + |
| +:model "ET-2710 Series" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x1143" |
| +:status :complete |
| + |
| +:model "" |
| +:interface "USB" |
| +:usbid "0x04b8" "0x00" |
| +:status :complete |