kopia lustrzana https://gitlab.com/sane-project/backends
3655 wiersze
106 KiB
C
3655 wiersze
106 KiB
C
/*
|
|
* epsonds.c - Epson ESC/I-2 driver.
|
|
*
|
|
* Copyright (C) 2015 Tower Technologies
|
|
* Author: Alessandro Zummo <a.zummo@towertech.it>
|
|
*
|
|
* This file is part of the SANE package.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation, version 2.
|
|
*/
|
|
|
|
#define EPSONDS_VERSION 1
|
|
#define EPSONDS_REVISION 1
|
|
#define EPSONDS_BUILD 0
|
|
|
|
/* debugging levels:
|
|
*
|
|
* 32 eds_send
|
|
* 30 eds_recv
|
|
* 20 sane_read and related
|
|
* 18 sane_read and related
|
|
* 17 setvalue, getvalue, control_option
|
|
* 16
|
|
* 15 esci2_img
|
|
* 13 image_cb
|
|
* 12 eds_control
|
|
* 11 all received params
|
|
* 10 some received params
|
|
* 9
|
|
* 8 esci2_xxx
|
|
* 7 open/close/attach
|
|
* 6 print_params
|
|
* 5 basic functions
|
|
* 3 JPEG decompressor
|
|
* 1 scanner info and capabilities
|
|
* 0 errors
|
|
*/
|
|
|
|
#include "sane/config.h"
|
|
|
|
#include <ctype.h>
|
|
#ifdef HAVE_SYS_SELECT_H
|
|
#include <sys/select.h>
|
|
#endif
|
|
#ifdef HAVE_SYS_TIME_H
|
|
# include <sys/time.h>
|
|
#endif
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
#include <math.h>
|
|
|
|
#include "sane/saneopts.h"
|
|
#include "sane/sanei_config.h"
|
|
#include "sane/sanei_tcp.h"
|
|
#include "sane/sanei_udp.h"
|
|
|
|
#include "epsonds.h"
|
|
#include "epsonds-usb.h"
|
|
#include "epsonds-io.h"
|
|
#include "epsonds-cmd.h"
|
|
#include "epsonds-ops.h"
|
|
#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.
|
|
*
|
|
* 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},
|
|
{0x118A, "PID 118A","ET-2810 Series", 7},
|
|
{0x118A, "PID 118A","L3250 Series", 7},
|
|
{0x119B, "PID 119B","XP-2150 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},
|
|
{1, 0x02, 0x00, 8},
|
|
{0, 0x00, 0x30, 1}
|
|
};
|
|
|
|
static SANE_String_Const mode_list[] = {
|
|
SANE_VALUE_SCAN_MODE_LINEART,
|
|
SANE_VALUE_SCAN_MODE_GRAY,
|
|
SANE_VALUE_SCAN_MODE_COLOR,
|
|
NULL
|
|
};
|
|
|
|
|
|
/* Define the different scan sources */
|
|
|
|
#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[] = {
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
/*
|
|
* List of pointers to devices - will be dynamically allocated depending
|
|
* on the number of devices found.
|
|
*/
|
|
static const SANE_Device **devlist;
|
|
|
|
/* Some utility functions */
|
|
|
|
static size_t
|
|
max_string_size(const SANE_String_Const strings[])
|
|
{
|
|
size_t size, max_size = 0;
|
|
int i;
|
|
|
|
for (i = 0; strings[i]; i++) {
|
|
size = strlen(strings[i]) + 1;
|
|
if (size > max_size)
|
|
max_size = size;
|
|
}
|
|
return max_size;
|
|
}
|
|
|
|
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)
|
|
{
|
|
DBG(6, "params.format = %d\n", params.format);
|
|
DBG(6, "params.last_frame = %d\n", params.last_frame);
|
|
DBG(6, "params.bytes_per_line = %d\n", params.bytes_per_line);
|
|
DBG(6, "params.pixels_per_line = %d\n", params.pixels_per_line);
|
|
DBG(6, "params.lines = %d\n", params.lines);
|
|
DBG(6, "params.depth = %d\n", params.depth);
|
|
}
|
|
|
|
static void
|
|
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;
|
|
|
|
if (s->locked) {
|
|
DBG(7, " unlocking scanner\n");
|
|
esci2_fin(s);
|
|
}
|
|
|
|
if (s->hw->connection == SANE_EPSONDS_NET) {
|
|
epsonds_net_unlock(s);
|
|
sanei_tcp_close(s->fd);
|
|
} else if (s->hw->connection == SANE_EPSONDS_USB) {
|
|
sanei_usb_close(s->fd);
|
|
}
|
|
|
|
free:
|
|
|
|
free(s->front.ring);
|
|
free(s->back.ring);
|
|
free(s->line_buffer);
|
|
free(s);
|
|
|
|
DBG(7, "%s: ZZZ\n", __func__);
|
|
}
|
|
|
|
static SANE_Status
|
|
open_scanner(epsonds_scanner *s)
|
|
{
|
|
SANE_Status status = SANE_STATUS_INVAL;
|
|
|
|
DBG(7, "%s: %s\n", __func__, s->hw->sane.name);
|
|
|
|
if (s->fd != -1) {
|
|
DBG(5, "scanner is already open: fd = %d\n", s->fd);
|
|
return SANE_STATUS_GOOD; /* no need to open the scanner */
|
|
}
|
|
|
|
if (s->hw->connection == SANE_EPSONDS_NET) {
|
|
unsigned char buf[5];
|
|
|
|
/* device name has the form net:ipaddr */
|
|
status = sanei_tcp_open(&s->hw->name[4], 1865, &s->fd);
|
|
if (status == SANE_STATUS_GOOD) {
|
|
|
|
ssize_t read;
|
|
struct timeval tv;
|
|
|
|
tv.tv_sec = 5;
|
|
tv.tv_usec = 0;
|
|
|
|
setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
|
|
|
|
s->netlen = 0;
|
|
|
|
DBG(32, "awaiting welcome message\n");
|
|
|
|
/* the scanner sends a kind of welcome msg */
|
|
// XXX check command type, answer to connect is 0x80
|
|
read = eds_recv(s, buf, 5, &status);
|
|
if (read != 5) {
|
|
sanei_tcp_close(s->fd);
|
|
s->fd = -1;
|
|
return SANE_STATUS_IO_ERROR;
|
|
}
|
|
|
|
DBG(32, "welcome message received, locking the scanner...\n");
|
|
|
|
/* lock the scanner for use by sane */
|
|
status = epsonds_net_lock(s);
|
|
if (status != SANE_STATUS_GOOD) {
|
|
DBG(1, "%s cannot lock scanner: %s\n", s->hw->sane.name,
|
|
sane_strstatus(status));
|
|
|
|
sanei_tcp_close(s->fd);
|
|
s->fd = -1;
|
|
|
|
return status;
|
|
}
|
|
|
|
DBG(32, "scanner locked\n");
|
|
}
|
|
|
|
} 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);
|
|
}
|
|
|
|
} else {
|
|
DBG(1, "unknown connection type: %d\n", s->hw->connection);
|
|
}
|
|
|
|
if (status == SANE_STATUS_ACCESS_DENIED) {
|
|
DBG(1, "please check that you have permissions on the device.\n");
|
|
DBG(1, "if this is a multi-function device with a printer,\n");
|
|
DBG(1, "disable any conflicting driver (like usblp).\n");
|
|
}
|
|
|
|
if (status != SANE_STATUS_GOOD)
|
|
DBG(1, "%s open failed: %s\n",
|
|
s->hw->sane.name,
|
|
sane_strstatus(status));
|
|
else
|
|
DBG(5, " opened correctly\n");
|
|
|
|
return status;
|
|
}
|
|
|
|
static int num_devices; /* number of scanners attached to backend */
|
|
static epsonds_device *first_dev; /* first EPSON scanner in list */
|
|
|
|
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;
|
|
return NULL;
|
|
}
|
|
|
|
/* clear verything */
|
|
memset(s, 0x00, sizeof(struct epsonds_scanner));
|
|
|
|
s->fd = -1;
|
|
s->hw = dev;
|
|
|
|
return s;
|
|
}
|
|
|
|
static struct epsonds_scanner *
|
|
device_detect(const char *name, int type, SANE_Status *status)
|
|
{
|
|
struct epsonds_scanner *s;
|
|
struct epsonds_device *dev;
|
|
|
|
DBG(1, "%s, %s, type: %d\n", __func__, name, type);
|
|
|
|
/* try to find the device in our list */
|
|
for (dev = first_dev; dev; dev = dev->next) {
|
|
|
|
if (strcmp(dev->sane.name, name) == 0) {
|
|
|
|
DBG(1, " found cached device\n");
|
|
|
|
// the device might have been just probed, sleep a bit.
|
|
if (dev->connection == SANE_EPSONDS_NET) {
|
|
sleep(1);
|
|
}
|
|
|
|
return scanner_create(dev, status);
|
|
}
|
|
}
|
|
|
|
/* not found, create new if valid */
|
|
if (type == SANE_EPSONDS_NODEV) {
|
|
*status = SANE_STATUS_INVAL;
|
|
return NULL;
|
|
}
|
|
|
|
/* alloc and clear our device structure */
|
|
dev = malloc(sizeof(*dev));
|
|
if (!dev) {
|
|
*status = SANE_STATUS_NO_MEM;
|
|
return NULL;
|
|
}
|
|
memset(dev, 0x00, sizeof(struct epsonds_device));
|
|
|
|
s = scanner_create(dev, status);
|
|
if (s == NULL)
|
|
return NULL;
|
|
|
|
dev->connection = type;
|
|
dev->model = strdup("(undetermined)");
|
|
dev->name = strdup(name);
|
|
|
|
dev->sane.name = dev->name;
|
|
dev->sane.vendor = "Epson";
|
|
dev->sane.model = dev->model;
|
|
dev->sane.type = "ESC/I-2";
|
|
|
|
*status = open_scanner(s);
|
|
if (*status != SANE_STATUS_GOOD) {
|
|
free(s);
|
|
return NULL;
|
|
}
|
|
|
|
eds_dev_init(dev);
|
|
|
|
/* lock scanner */
|
|
*status = eds_lock(s);
|
|
if (*status != SANE_STATUS_GOOD) {
|
|
goto close;
|
|
}
|
|
|
|
/* discover capabilities */
|
|
*status = esci2_info(s);
|
|
if (*status != SANE_STATUS_GOOD)
|
|
goto close;
|
|
|
|
*status = esci2_capa(s);
|
|
if (*status != SANE_STATUS_GOOD)
|
|
goto close;
|
|
|
|
*status = esci2_resa(s);
|
|
if (*status != SANE_STATUS_GOOD)
|
|
goto close;
|
|
|
|
// assume 1 and 8 bit are always supported
|
|
eds_add_depth(s->hw, 1);
|
|
eds_add_depth(s->hw, 8);
|
|
|
|
// setup area according to available options
|
|
if (s->hw->has_fb) {
|
|
|
|
dev->x_range = &dev->fbf_x_range;
|
|
dev->y_range = &dev->fbf_y_range;
|
|
dev->alignment = dev->fbf_alignment;
|
|
|
|
} else if (s->hw->has_adf) {
|
|
|
|
dev->x_range = &dev->adf_x_range;
|
|
dev->y_range = &dev->adf_y_range;
|
|
dev->alignment = dev->adf_alignment;
|
|
|
|
} else {
|
|
DBG(0, "unable to lay on the flatbed or feed the feeder. is that a scanner??\n");
|
|
}
|
|
|
|
*status = eds_dev_post_init(dev);
|
|
if (*status != SANE_STATUS_GOOD)
|
|
goto close;
|
|
|
|
DBG(1, "scanner model: %s\n", dev->model);
|
|
|
|
|
|
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);
|
|
|
|
s->hw->model = strdup(map->deviceID);
|
|
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;
|
|
first_dev = dev;
|
|
|
|
return s;
|
|
|
|
close:
|
|
DBG(1, " failed\n");
|
|
|
|
close_scanner(s);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static SANE_Status
|
|
attach(const char *name, int type)
|
|
{
|
|
SANE_Status status;
|
|
epsonds_scanner * s;
|
|
|
|
DBG(7, "%s: devname = %s, type = %d\n", __func__, name, type);
|
|
|
|
s = device_detect(name, type, &status);
|
|
if (s == NULL)
|
|
return status;
|
|
|
|
close_scanner(s);
|
|
return status;
|
|
}
|
|
|
|
SANE_Status
|
|
attach_one_usb(const char *dev)
|
|
{
|
|
DBG(7, "%s: dev = %s\n", __func__, dev);
|
|
return attach(dev, SANE_EPSONDS_USB);
|
|
}
|
|
|
|
static SANE_Status
|
|
attach_one_net(const char *dev)
|
|
{
|
|
char name[39 + 4];
|
|
|
|
DBG(7, "%s: dev = %s\n", __func__, dev);
|
|
|
|
strcpy(name, "net:");
|
|
strcat(name, 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,
|
|
void *data)
|
|
{
|
|
int vendor, product;
|
|
SANE_Bool local_only = *(SANE_Bool*) data;
|
|
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");
|
|
|
|
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");
|
|
|
|
if (vendor != SANE_EPSONDS_VENDOR_ID)
|
|
return SANE_STATUS_INVAL; /* this is not an Epson device */
|
|
|
|
sanei_usb_attach_matching_devices(line, attach_one_usb);
|
|
|
|
} else if (strncmp(line, "usb", 3) == 0 && len == 3) {
|
|
|
|
DBG(7, " probing usb devices\n");
|
|
|
|
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) {
|
|
|
|
if (!local_only) {
|
|
/* remove the "net" sub string */
|
|
const char *name =
|
|
sanei_config_skip_whitespace(line + 3);
|
|
|
|
if (strncmp(name, "autodiscovery", 13) == 0)
|
|
{
|
|
#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);
|
|
}
|
|
|
|
return SANE_STATUS_GOOD;
|
|
}
|
|
|
|
static void
|
|
free_devices(void)
|
|
{
|
|
epsonds_device *dev, *next;
|
|
|
|
for (dev = first_dev; dev; dev = next) {
|
|
next = dev->next;
|
|
free(dev->name);
|
|
free(dev->model);
|
|
free(dev);
|
|
}
|
|
|
|
free(devlist);
|
|
first_dev = NULL;
|
|
}
|
|
|
|
static void
|
|
probe_devices(SANE_Bool local_only)
|
|
{
|
|
DBG(5, "%s\n", __func__);
|
|
|
|
free_devices();
|
|
sanei_configure_attach(EPSONDS_CONFIG_FILE, NULL,
|
|
attach_one_config, &local_only);
|
|
}
|
|
|
|
/**** SANE API ****/
|
|
|
|
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",
|
|
EPSONDS_VERSION, EPSONDS_REVISION, EPSONDS_BUILD);
|
|
|
|
if (version_code != NULL)
|
|
*version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR,
|
|
EPSONDS_BUILD);
|
|
|
|
sanei_usb_init();
|
|
|
|
return SANE_STATUS_GOOD;
|
|
}
|
|
|
|
void
|
|
sane_exit(void)
|
|
{
|
|
DBG(5, "** %s\n", __func__);
|
|
free_profile_maps(&stProfileMapArray);
|
|
free_devices();
|
|
}
|
|
|
|
SANE_Status
|
|
sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)
|
|
{
|
|
int i;
|
|
epsonds_device *dev;
|
|
|
|
DBG(5, "** %s local_only = %d \n", __func__, local_only);
|
|
|
|
|
|
probe_devices(local_only);
|
|
|
|
devlist = malloc((num_devices + 1) * sizeof(devlist[0]));
|
|
if (!devlist) {
|
|
DBG(1, "out of memory (line %d)\n", __LINE__);
|
|
return SANE_STATUS_NO_MEM;
|
|
}
|
|
|
|
DBG(5, "%s - results:\n", __func__);
|
|
|
|
for (i = 0, dev = first_dev; i < num_devices && dev; dev = dev->next, i++) {
|
|
DBG(1, " %d (%d): %s\n", i, dev->connection, dev->model);
|
|
devlist[i] = &dev->sane;
|
|
}
|
|
|
|
devlist[i] = NULL;
|
|
|
|
*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++) {
|
|
s->opt[i].size = sizeof(SANE_Word);
|
|
s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
|
|
}
|
|
|
|
s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
|
|
s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
|
|
s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
|
|
s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
|
|
s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
|
|
|
|
/* "Scan Mode" group: */
|
|
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;
|
|
s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
|
|
s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
|
|
s->opt[OPT_MODE].type = SANE_TYPE_STRING;
|
|
s->opt[OPT_MODE].size = max_string_size(mode_list);
|
|
s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
|
|
s->opt[OPT_MODE].constraint.string_list = mode_list;
|
|
s->val[OPT_MODE].w = 0; /* Lineart */
|
|
|
|
/* bit depth */
|
|
s->opt[OPT_DEPTH].name = SANE_NAME_BIT_DEPTH;
|
|
s->opt[OPT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
|
|
s->opt[OPT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
|
|
s->opt[OPT_DEPTH].type = SANE_TYPE_INT;
|
|
s->opt[OPT_DEPTH].unit = SANE_UNIT_BIT;
|
|
s->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
|
|
s->opt[OPT_DEPTH].constraint.word_list = s->hw->depth_list;
|
|
s->val[OPT_DEPTH].w = s->hw->depth_list[1]; /* the first "real" element is the default */
|
|
|
|
/* default is Lineart, disable depth selection */
|
|
s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
|
|
|
|
/* resolution */
|
|
s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
|
|
s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
|
|
s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
|
|
|
|
s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
|
|
s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
|
|
|
|
/* range */
|
|
if (s->hw->dpi_range.quant) {
|
|
s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
|
|
s->opt[OPT_RESOLUTION].constraint.range = &s->hw->dpi_range;
|
|
s->val[OPT_RESOLUTION].w = s->hw->dpi_range.min;
|
|
} else { /* list */
|
|
s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
|
|
s->opt[OPT_RESOLUTION].constraint.word_list = s->hw->res_list;
|
|
s->val[OPT_RESOLUTION].w = s->hw->res_list[1];
|
|
}
|
|
|
|
/* "Geometry" group: */
|
|
s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N("Geometry");
|
|
s->opt[OPT_GEOMETRY_GROUP].desc = "";
|
|
s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
|
|
s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
|
|
|
|
/* top-left x */
|
|
s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
|
|
s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
|
|
s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
|
|
s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
|
|
s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
|
|
s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
|
|
s->opt[OPT_TL_X].constraint.range = s->hw->x_range;
|
|
s->val[OPT_TL_X].w = 0;
|
|
|
|
/* top-left y */
|
|
s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
|
|
s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
|
|
s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
|
|
|
|
s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
|
|
s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
|
|
s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
|
|
s->opt[OPT_TL_Y].constraint.range = s->hw->y_range;
|
|
s->val[OPT_TL_Y].w = 0;
|
|
|
|
/* bottom-right x */
|
|
s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
|
|
s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
|
|
s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
|
|
|
|
s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
|
|
s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
|
|
s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
|
|
s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
|
|
s->val[OPT_BR_X].w = s->hw->x_range->max;
|
|
|
|
/* bottom-right y */
|
|
s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
|
|
s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
|
|
s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
|
|
|
|
s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
|
|
s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
|
|
s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
|
|
s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
|
|
s->val[OPT_BR_Y].w = s->hw->y_range->max;
|
|
|
|
/* "Optional equipment" group: */
|
|
s->opt[OPT_EQU_GROUP].title = SANE_I18N("Optional equipment");
|
|
s->opt[OPT_EQU_GROUP].desc = "";
|
|
s->opt[OPT_EQU_GROUP].type = SANE_TYPE_GROUP;
|
|
s->opt[OPT_EQU_GROUP].cap = SANE_CAP_ADVANCED;
|
|
|
|
/* source */
|
|
s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
|
|
s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
|
|
s->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
|
|
s->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
|
|
s->opt[OPT_SOURCE].size = max_string_size(source_list);
|
|
s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
|
|
s->opt[OPT_SOURCE].constraint.string_list = source_list;
|
|
s->val[OPT_SOURCE].w = 0;
|
|
|
|
s->opt[OPT_EJECT].name = "eject";
|
|
s->opt[OPT_EJECT].title = SANE_I18N("Eject");
|
|
s->opt[OPT_EJECT].desc = SANE_I18N("Eject the sheet in the ADF");
|
|
s->opt[OPT_EJECT].type = SANE_TYPE_BUTTON;
|
|
|
|
if (!s->hw->adf_has_eject)
|
|
s->opt[OPT_EJECT].cap |= SANE_CAP_INACTIVE;
|
|
|
|
s->opt[OPT_LOAD].name = "load";
|
|
s->opt[OPT_LOAD].title = SANE_I18N("Load");
|
|
s->opt[OPT_LOAD].desc = SANE_I18N("Load a sheet in the ADF");
|
|
s->opt[OPT_LOAD].type = SANE_TYPE_BUTTON;
|
|
|
|
if (!s->hw->adf_has_load)
|
|
s->opt[OPT_LOAD].cap |= SANE_CAP_INACTIVE;
|
|
|
|
|
|
s->opt[OPT_ADF_SKEW].name = "adf-skew";
|
|
s->opt[OPT_ADF_SKEW].title = SANE_I18N("ADF Skew Correction");
|
|
s->opt[OPT_ADF_SKEW].desc =
|
|
SANE_I18N("Enables ADF skew correction");
|
|
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;
|
|
}
|
|
|
|
SANE_Status
|
|
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 */
|
|
if (name[0] == '\0') {
|
|
|
|
probe_devices(SANE_FALSE);
|
|
|
|
if (first_dev == NULL) {
|
|
DBG(1, "no devices detected\n");
|
|
return SANE_STATUS_INVAL;
|
|
}
|
|
|
|
s = device_detect(first_dev->sane.name, first_dev->connection,
|
|
&status);
|
|
if (s == NULL) {
|
|
DBG(1, "cannot open a perfectly valid device (%s),"
|
|
" please report to the authors\n", name);
|
|
return SANE_STATUS_INVAL;
|
|
}
|
|
|
|
} else {
|
|
|
|
if (strncmp(name, "net:", 4) == 0) {
|
|
s = device_detect(name, SANE_EPSONDS_NET, &status);
|
|
if (s == NULL)
|
|
return status;
|
|
} else if (strncmp(name, "libusb:", 7) == 0) {
|
|
s = device_detect(name, SANE_EPSONDS_USB, &status);
|
|
if (s == NULL)
|
|
return status;
|
|
} else {
|
|
DBG(1, "invalid device name: %s\n", name);
|
|
return SANE_STATUS_INVAL;
|
|
}
|
|
}
|
|
|
|
/* s is always valid here */
|
|
|
|
DBG(5, "%s: handle obtained\n", __func__);
|
|
|
|
init_options(s);
|
|
|
|
*handle = (SANE_Handle)s;
|
|
|
|
status = open_scanner(s);
|
|
if (status != SANE_STATUS_GOOD) {
|
|
free(s);
|
|
return status;
|
|
}
|
|
|
|
/* lock scanner if required */
|
|
if (!s->locked) {
|
|
status = eds_lock(s);
|
|
}
|
|
|
|
setvalue((SANE_Handle)s, OPT_MODE, (void*)SANE_VALUE_SCAN_MODE_COLOR, NULL);
|
|
|
|
return status;
|
|
}
|
|
|
|
void
|
|
sane_close(SANE_Handle handle)
|
|
{
|
|
epsonds_scanner *s = (epsonds_scanner *)handle;
|
|
|
|
DBG(1, "** %s\n", __func__);
|
|
|
|
close_scanner(s);
|
|
}
|
|
|
|
const SANE_Option_Descriptor *
|
|
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)
|
|
{
|
|
epsonds_scanner *s = (epsonds_scanner *) handle;
|
|
|
|
if (option < 0 || option >= NUM_OPTIONS)
|
|
return NULL;
|
|
|
|
return s->opt + option;
|
|
}
|
|
|
|
static const SANE_String_Const *
|
|
search_string_list(const SANE_String_Const *list, SANE_String value)
|
|
{
|
|
while (*list != NULL && strcmp(value, *list) != 0)
|
|
list++;
|
|
|
|
return ((*list == NULL) ? NULL : list);
|
|
}
|
|
|
|
/*
|
|
* Handles setting the source (flatbed, transparency adapter (TPU),
|
|
* or auto document feeder (ADF)).
|
|
*
|
|
* For newer scanners it also sets the focus according to the
|
|
* glass / TPU settings.
|
|
*/
|
|
|
|
static void
|
|
change_source(epsonds_scanner *s, SANE_Int optindex, char *value)
|
|
{
|
|
int force_max = SANE_FALSE;
|
|
|
|
DBG(1, "%s: optindex = %d, source = '%s'\n", __func__, optindex,
|
|
value);
|
|
|
|
s->val[OPT_SOURCE].w = optindex;
|
|
|
|
/* if current selected area is the maximum available,
|
|
* keep this setting on the new source.
|
|
*/
|
|
if (s->val[OPT_TL_X].w == s->hw->x_range->min
|
|
&& s->val[OPT_TL_Y].w == s->hw->y_range->min
|
|
&& s->val[OPT_BR_X].w == s->hw->x_range->max
|
|
&& s->val[OPT_BR_Y].w == s->hw->y_range->max) {
|
|
force_max = SANE_TRUE;
|
|
}
|
|
|
|
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;
|
|
|
|
|
|
} 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;
|
|
|
|
} else {
|
|
|
|
/* neither ADF nor TPU active, assume FB */
|
|
s->hw->x_range = &s->hw->fbf_x_range;
|
|
s->hw->y_range = &s->hw->fbf_y_range;
|
|
s->hw->alignment = s->hw->fbf_alignment;
|
|
}
|
|
|
|
s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
|
|
s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
|
|
|
|
if (s->val[OPT_TL_X].w < s->hw->x_range->min || force_max)
|
|
s->val[OPT_TL_X].w = s->hw->x_range->min;
|
|
|
|
if (s->val[OPT_TL_Y].w < s->hw->y_range->min || force_max)
|
|
s->val[OPT_TL_Y].w = s->hw->y_range->min;
|
|
|
|
if (s->val[OPT_BR_X].w > s->hw->x_range->max || force_max)
|
|
s->val[OPT_BR_X].w = s->hw->x_range->max;
|
|
|
|
if (s->val[OPT_BR_Y].w > s->hw->y_range->max || force_max)
|
|
s->val[OPT_BR_Y].w = s->hw->y_range->max;
|
|
}
|
|
|
|
static SANE_Status
|
|
getvalue(SANE_Handle handle, SANE_Int option, void *value)
|
|
{
|
|
epsonds_scanner *s = (epsonds_scanner *)handle;
|
|
SANE_Option_Descriptor *sopt = &(s->opt[option]);
|
|
Option_Value *sval = &(s->val[option]);
|
|
|
|
DBG(17, "%s: option = %d\n", __func__, option);
|
|
|
|
switch (option) {
|
|
|
|
case OPT_NUM_OPTS:
|
|
case OPT_RESOLUTION:
|
|
case OPT_TL_X:
|
|
case OPT_TL_Y:
|
|
case OPT_BR_X:
|
|
case OPT_BR_Y:
|
|
case OPT_DEPTH:
|
|
case OPT_ADF_SKEW:
|
|
*((SANE_Word *) value) = sval->w;
|
|
break;
|
|
|
|
case OPT_MODE:
|
|
case OPT_SOURCE:
|
|
strcpy((char *) value, sopt->constraint.string_list[sval->w]);
|
|
break;
|
|
|
|
default:
|
|
return SANE_STATUS_INVAL;
|
|
}
|
|
|
|
return SANE_STATUS_GOOD;
|
|
}
|
|
|
|
static SANE_Status
|
|
setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)
|
|
{
|
|
epsonds_scanner *s = (epsonds_scanner *) handle;
|
|
SANE_Option_Descriptor *sopt = &(s->opt[option]);
|
|
Option_Value *sval = &(s->val[option]);
|
|
|
|
SANE_Status status;
|
|
const SANE_String_Const *optval = NULL;
|
|
int optindex = 0;
|
|
SANE_Bool reload = SANE_FALSE;
|
|
|
|
DBG(17, "** %s: option = %d, value = %p\n", __func__, option, value);
|
|
|
|
status = sanei_constrain_value(sopt, value, info);
|
|
if (status != SANE_STATUS_GOOD)
|
|
return status;
|
|
|
|
if (info && value && (*info & SANE_INFO_INEXACT)
|
|
&& sopt->type == SANE_TYPE_INT)
|
|
DBG(17, " constrained val = %d\n", *(SANE_Word *) value);
|
|
|
|
if (sopt->constraint_type == SANE_CONSTRAINT_STRING_LIST) {
|
|
optval = search_string_list(sopt->constraint.string_list,
|
|
(char *) value);
|
|
if (optval == NULL)
|
|
return SANE_STATUS_INVAL;
|
|
optindex = optval - sopt->constraint.string_list;
|
|
}
|
|
|
|
/* block faulty frontends */
|
|
if (sopt->cap & SANE_CAP_INACTIVE) {
|
|
DBG(1, " tried to modify a disabled parameter");
|
|
return SANE_STATUS_INVAL;
|
|
}
|
|
|
|
switch (option) {
|
|
|
|
case OPT_ADF_SKEW:
|
|
case OPT_RESOLUTION:
|
|
case OPT_ADF_CRP:
|
|
sval->w = *((SANE_Word *) value);
|
|
reload = SANE_TRUE;
|
|
break;
|
|
|
|
case OPT_BR_X:
|
|
case OPT_BR_Y:
|
|
if (SANE_UNFIX(*((SANE_Word *) value)) == 0) {
|
|
DBG(17, " invalid br-x or br-y\n");
|
|
return SANE_STATUS_INVAL;
|
|
}
|
|
// 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:
|
|
change_source(s, optindex, (char *) value);
|
|
reload = SANE_TRUE;
|
|
break;
|
|
|
|
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;
|
|
} else {
|
|
s->mode_jpeg = 0;
|
|
}
|
|
|
|
sval->w = optindex;
|
|
|
|
/* if binary, then disable the bit depth selection */
|
|
if (optindex == 0) {
|
|
s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
|
|
} else {
|
|
if (s->hw->depth_list[0] == 1)
|
|
s->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
|
|
else {
|
|
s->opt[OPT_DEPTH].cap &= ~SANE_CAP_INACTIVE;
|
|
s->val[OPT_DEPTH].w =
|
|
mode_params[optindex].depth;
|
|
}
|
|
}
|
|
|
|
reload = SANE_TRUE;
|
|
break;
|
|
}
|
|
|
|
case OPT_DEPTH:
|
|
sval->w = *((SANE_Word *) value);
|
|
mode_params[s->val[OPT_MODE].w].depth = sval->w;
|
|
reload = SANE_TRUE;
|
|
break;
|
|
|
|
case OPT_LOAD:
|
|
esci2_mech(s, "#ADFLOAD");
|
|
break;
|
|
|
|
case OPT_EJECT:
|
|
esci2_mech(s, "#ADFEJCT");
|
|
break;
|
|
|
|
default:
|
|
return SANE_STATUS_INVAL;
|
|
}
|
|
|
|
if (reload && info != NULL)
|
|
*info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
|
|
|
|
return SANE_STATUS_GOOD;
|
|
}
|
|
|
|
SANE_Status
|
|
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action,
|
|
void *value, SANE_Int *info)
|
|
{
|
|
DBG(17, "** %s: action = %x, option = %d\n", __func__, action, option);
|
|
|
|
if (option < 0 || option >= NUM_OPTIONS)
|
|
return SANE_STATUS_INVAL;
|
|
|
|
if (info != NULL)
|
|
*info = 0;
|
|
|
|
switch (action) {
|
|
case SANE_ACTION_GET_VALUE:
|
|
return getvalue(handle, option, value);
|
|
|
|
case SANE_ACTION_SET_VALUE:
|
|
return setvalue(handle, option, value, info);
|
|
|
|
default:
|
|
return SANE_STATUS_INVAL;
|
|
}
|
|
|
|
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)
|
|
{
|
|
epsonds_scanner *s = (epsonds_scanner *)handle;
|
|
|
|
DBG(5, "** %s\n", __func__);
|
|
|
|
if (params == NULL)
|
|
DBG(1, "%s: params is NULL\n", __func__);
|
|
|
|
/*
|
|
* If sane_start was already called, then just retrieve the parameters
|
|
* from the scanner data structure
|
|
*/
|
|
if (s->scanning) {
|
|
DBG(5, "scan in progress, returning saved params structure\n");
|
|
} else {
|
|
/* otherwise initialize the params structure */
|
|
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);
|
|
|
|
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[CMD_BUF_SIZE]; /* take care not to overflow */
|
|
SANE_Status status = 0;
|
|
|
|
s->pages++;
|
|
|
|
DBG(5, "** %s, pages = %d, scanning = %d, backside = %d, front fill: %d, back fill: %d\n",
|
|
__func__, s->pages, s->scanning, s->backside,
|
|
eds_ring_avail(&s->front),
|
|
eds_ring_avail(&s->back));
|
|
|
|
s->eof = 0;
|
|
s->canceling = 0;
|
|
s->acquirePage = 0;
|
|
|
|
if ((s->pages % 2) == 1) {
|
|
s->current = &s->front;
|
|
} else if (eds_ring_avail(&s->back)) {
|
|
DBG(5, "back side\n");
|
|
s->current = &s->back;
|
|
}
|
|
|
|
/* scan already in progress? (one pass adf) */
|
|
if (s->scanning || eds_ring_avail(&s->back) > 0) {
|
|
DBG(5, " scan in progress, returning early\n");
|
|
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 */
|
|
status = eds_init_parameters(s);
|
|
if (status != SANE_STATUS_GOOD) {
|
|
DBG(1, " parameters initialization failed\n");
|
|
return status;
|
|
}
|
|
|
|
/* allocate line buffer */
|
|
s->line_buffer = realloc(s->line_buffer, s->params.bytes_per_line);
|
|
if (s->line_buffer == NULL)
|
|
return SANE_STATUS_NO_MEM;
|
|
|
|
/* transfer buffer size, bsz */
|
|
/* XXX read value from scanner */
|
|
s->bsz = (1048576 * 4);
|
|
|
|
/* transfer buffer */
|
|
s->buf = realloc(s->buf, s->bsz);
|
|
if (s->buf == NULL)
|
|
return SANE_STATUS_NO_MEM;
|
|
|
|
print_params(s->params);
|
|
|
|
/* set scanning parameters */
|
|
|
|
s->isDuplexScan = 0;
|
|
/* document source */
|
|
if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) {
|
|
|
|
SANE_Int status = esci2_stat(s);
|
|
if (status == SANE_STATUS_NO_DOCS)
|
|
{
|
|
return SANE_STATUS_NO_DOCS;
|
|
}
|
|
|
|
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 */
|
|
}
|
|
|
|
strcpy(cmd, buf);
|
|
|
|
s->needToConvertBW = 0;
|
|
|
|
if (s->params.format == SANE_FRAME_GRAY) {
|
|
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);
|
|
}
|
|
|
|
strcat(cmd, buf);
|
|
|
|
/* image transfer format */
|
|
if (!s->mode_jpeg) {
|
|
if (s->params.depth > 1 || s->hw->has_raw) {
|
|
strcat(cmd, "#FMTRAW ");
|
|
}
|
|
} else {
|
|
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 (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);
|
|
}
|
|
|
|
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);
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
/* start scanning */
|
|
DBG(1, "%s: scanning...\n", __func__);
|
|
|
|
/* switch to data state */
|
|
status = esci2_trdt(s);
|
|
if (status != SANE_STATUS_GOOD) {
|
|
goto end;
|
|
}
|
|
|
|
/* 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));
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
static SANE_Status acquire_jpeg_data(epsonds_scanner* s)
|
|
{
|
|
|
|
SANE_Int read = 0;
|
|
|
|
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 */
|
|
if (available > 0) {
|
|
|
|
DBG(18, "reading from ring buffer, %d left\n", available);
|
|
|
|
eds_copy_image_from_ring(s, data, max_length, &read);
|
|
|
|
// data is empty fin
|
|
if (read == 0) {
|
|
*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{
|
|
*length = 0;
|
|
eds_ring_flush(s->current);
|
|
eds_ring_destory(s->current);
|
|
DBG(18, "returns EOF 1\n");
|
|
return SANE_STATUS_EOF;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* void sane_cancel(SANE_Handle handle)
|
|
*
|
|
* Set the cancel flag to true. The next time the backend requests data
|
|
* from the scanner the CAN message will be sent.
|
|
*/
|
|
|
|
void
|
|
sane_cancel(SANE_Handle handle)
|
|
{
|
|
DBG(1, "** %s\n", __func__);
|
|
((epsonds_scanner *)handle)->canceling = SANE_TRUE;
|
|
}
|
|
|
|
/*
|
|
* SANE_Status sane_set_io_mode()
|
|
*
|
|
* not supported - for asynchronous I/O
|
|
*/
|
|
|
|
SANE_Status
|
|
sane_set_io_mode(SANE_Handle __sane_unused__ handle,
|
|
SANE_Bool __sane_unused__ non_blocking)
|
|
{
|
|
return SANE_STATUS_UNSUPPORTED;
|
|
}
|
|
|
|
/*
|
|
* SANE_Status sane_get_select_fd()
|
|
*
|
|
* not supported - for asynchronous I/O
|
|
*/
|
|
|
|
SANE_Status
|
|
sane_get_select_fd(SANE_Handle __sane_unused__ handle,
|
|
SANE_Int __sane_unused__ *fd)
|
|
{
|
|
return SANE_STATUS_UNSUPPORTED;
|
|
}
|