diff options
Diffstat (limited to 'backend/epsonds.c')
| -rw-r--r-- | backend/epsonds.c | 2629 | 
1 files changed, 2382 insertions, 247 deletions
| diff --git a/backend/epsonds.c b/backend/epsonds.c index 1d557c9..0815535 100644 --- a/backend/epsonds.c +++ b/backend/epsonds.c @@ -50,6 +50,7 @@  #include <sys/types.h>  #include <sys/socket.h>  #include <unistd.h> +#include <math.h>  #include "sane/saneopts.h"  #include "sane/sanei_config.h" @@ -64,7 +65,8 @@  #include "epsonds-jpeg.h"  #include "epsonds-net.h" - +static SANE_Status +setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info);  /*   * Definition of the mode_param struct, that is used to   * specify the valid parameters for the different scan modes. @@ -72,6 +74,1234 @@   * 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}, @@ -86,16 +1316,12 @@ static SANE_String_Const mode_list[] = {  	NULL  }; -static const SANE_String_Const adf_mode_list[] = { -	SANE_I18N("Simplex"), -	SANE_I18N("Duplex"), -	NULL -};  /* Define the different scan sources */ -#define FBF_STR	SANE_I18N("Flatbed") -#define ADF_STR	SANE_I18N("Automatic Document Feeder") +#define STRING_FLATBED SANE_I18N("Flatbed") +#define STRING_ADFFRONT SANE_I18N("ADF Front") +#define STRING_ADFDUPLEX SANE_I18N("ADF Duplex")  /* order will be fixed: fb, adf, tpu */  SANE_String_Const source_list[] = { @@ -129,6 +1355,9 @@ max_string_size(const SANE_String_Const strings[])  static SANE_Status attach_one_usb(SANE_String_Const devname);  static SANE_Status attach_one_net(SANE_String_Const devname); +static SANE_Status acquire_jpeg_data(epsonds_scanner* s); +static SANE_Status acquire_and_decode_jpeg_data(epsonds_scanner* s); +static SANE_Status acquire_raw_data(epsonds_scanner* s);  static void  print_params(const SANE_Parameters params) @@ -146,6 +1375,11 @@ close_scanner(epsonds_scanner *s)  {  	DBG(7, "%s: fd = %d\n", __func__, s->fd); +	if (s->scanning) +	{ +		sane_cancel(s); +	} +  	if (s->fd == -1)  		goto free; @@ -171,49 +1405,6 @@ free:  	DBG(7, "%s: ZZZ\n", __func__);  } -static void -e2_network_discovery(void) -{ -	fd_set rfds; -	int fd, len; -	SANE_Status status; - -	char *ip, *query = "EPSONP\x00\xff\x00\x00\x00\x00\x00\x00\x00"; -	unsigned char buf[76]; - -	struct timeval to; - -	status = sanei_udp_open_broadcast(&fd); -	if (status != SANE_STATUS_GOOD) -		return; - -	sanei_udp_write_broadcast(fd, 3289, (unsigned char *) query, 15); - -	DBG(5, "%s, sent discovery packet\n", __func__); - -	to.tv_sec = 1; -	to.tv_usec = 0; - -	FD_ZERO(&rfds); -	FD_SET(fd, &rfds); - -	sanei_udp_set_nonblock(fd, SANE_TRUE); -	while (select(fd + 1, &rfds, NULL, NULL, &to) > 0) { -		if ((len = sanei_udp_recvfrom(fd, buf, 76, &ip)) == 76) { -			DBG(5, " response from %s\n", ip); - -			/* minimal check, protocol unknown */ -			if (strncmp((char *) buf, "EPSON", 5) == 0) -				attach_one_net(ip); -		} -	} - -	DBG(5, "%s, end\n", __func__); - -	sanei_udp_close(fd); -} - -  static SANE_Status  open_scanner(epsonds_scanner *s)  { @@ -230,7 +1421,7 @@ open_scanner(epsonds_scanner *s)  		unsigned char buf[5];  		/* device name has the form net:ipaddr */ -		status = sanei_tcp_open(&s->hw->sane.name[4], 1865, &s->fd); +		status = sanei_tcp_open(&s->hw->name[4], 1865, &s->fd);  		if (status == SANE_STATUS_GOOD) {  			ssize_t read; @@ -272,12 +1463,10 @@ open_scanner(epsonds_scanner *s)  		}  	} else if (s->hw->connection == SANE_EPSONDS_USB) { -  		status = sanei_usb_open(s->hw->sane.name, &s->fd);  		if (status == SANE_STATUS_GOOD) {  			sanei_usb_set_timeout(USB_TIMEOUT); -			sanei_usb_clear_halt(s->fd);  		}  	} else { @@ -307,7 +1496,6 @@ static struct epsonds_scanner *  scanner_create(struct epsonds_device *dev, SANE_Status *status)  {  	struct epsonds_scanner *s; -  	s = malloc(sizeof(struct epsonds_scanner));  	if (s == NULL) {  		*status = SANE_STATUS_NO_MEM; @@ -428,7 +1616,32 @@ device_detect(const char *name, int type, SANE_Status *status)  	DBG(1, "scanner model: %s\n", dev->model); -	/* add this scanner to the device list */ + +	s->hw->lut_id = 0; + +	for (int i = 0; i < stProfileMapArray.used; i++) { + +		epsonds_profile_map* map = &stProfileMapArray.array[i]; + + +		if (strcmp(map->productName, dev->model) == 0) { + +			{//Convert to user friendly model name +				free(s->hw->model); + +				char* deviceName = (char*)malloc(strlen(map->deviceID) + 1); +				memset(deviceName, 0, strlen(map->deviceID) + 1); +				strncpy(deviceName,  map->deviceID, strlen(map->deviceID)); +				s->hw->model = deviceName; +				s->hw->sane.model = s->hw->model; +			} +			{// set lutid +				s->hw->lut_id = map->lutID; +			} +			break; +		} +	} +	DBG(1, "scanner lut_id: %d\n", s->hw->lut_id);  	num_devices++;  	dev->next = first_dev; @@ -479,6 +1692,67 @@ attach_one_net(const char *dev)  	return attach(name, SANE_EPSONDS_NET);  } +static void found_net_device(const char* device_name, const char* ip) +{ +	DBG(7, "Found %s: ip = %s\n", device_name, ip); + +	int foundSupportedDevice = 0; + +	// search models +	for (int i = 0; i < stProfileMapArray.used; i++) { +		if (strcmp(stProfileMapArray.array[i].deviceID, device_name) == 0) { +			foundSupportedDevice = 1; +			break; +		} +	} + + +	if (foundSupportedDevice) +	{ +		char name[39 + 4]; + +		strcpy(name, "net:"); +		strncat(name, ip, 39); + +		int foundCache = 0; +		// search cache and prents duplicated model +		for (epsonds_device* dev = first_dev; dev; dev = dev->next) { +			if (strcmp(dev->sane.name, name) == 0) { +				foundCache = 1; +			} +		} +		if (foundCache == 0) +		{ +			attach(name, SANE_EPSONDS_NET); +		} +	} +} + +static void +splitProfileName(const char* input, int* outProductID, char *outProductName, char* outDeviceID, int* outLutID) +{ +    char target[1024]; +    strncpy(target, input, 1023); + +    strtok(target, ":");//profile + +    //productID +    char* pid = strtok(NULL, ","); +    sscanf(pid, "%x", (unsigned int*)outProductID); + +    //productName +    char* productName = strtok(NULL, ","); +    strncpy(outProductName, productName,  49); + +    //deviceID +    char* deviceID = strtok(NULL, ","); +    strncpy(outDeviceID, deviceID,  49); + +    //lutID +    char* lutID = strtok(NULL, ","); +    sscanf(lutID, "%d", outLutID); +} +  static SANE_Status  attach_one_config(SANEI_Config __sane_unused__ *config, const char *line, @@ -489,8 +1763,17 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line,  	int len = strlen(line);  	DBG(7, "%s: len = %d, line = %s\n", __func__, len, line); +	if (strncmp(line, "profile", 7) == 0 ) { +		DBG(7, " found profile device profile\n"); + +		epsonds_profile_map profle_map; + +		splitProfileName(line, &profle_map.productID, profle_map.productName, profle_map.deviceID, &profle_map.lutID); -	if (sscanf(line, "usb %i %i", &vendor, &product) == 2) { +		DBG(7, "Found profile : %x %s %s %d\n", profle_map.productID, profle_map.productName, profle_map.deviceID, profle_map.lutID); + +		insert_profile_map(&stProfileMapArray, profle_map); +	}else if (sscanf(line, "usb %i %i", &vendor, &product) == 2) {  		DBG(7, " user configured device\n"); @@ -501,15 +1784,11 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line,  	} else if (strncmp(line, "usb", 3) == 0 && len == 3) { -		int i, numIds; -  		DBG(7, " probing usb devices\n"); -		numIds = epsonds_get_number_of_ids(); - -		for (i = 0; i < numIds; i++) { -			sanei_usb_find_devices(SANE_EPSONDS_VENDOR_ID, -					epsonds_usb_product_ids[i], attach_one_usb); +		for (int i = 0; i < stProfileMapArray.used; i++) { +			int usbPid = stProfileMapArray.array[i].productID; +			sanei_usb_find_devices(SANE_EPSONDS_VENDOR_ID, usbPid, attach_one_usb);  		}  	} else if (strncmp(line, "net", 3) == 0) { @@ -520,11 +1799,17 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line,  				sanei_config_skip_whitespace(line + 3);  			if (strncmp(name, "autodiscovery", 13) == 0) -				e2_network_discovery(); +			{ +				#if WITH_AVAHI +				epsonds_searchDevices(found_net_device); +				#else +				// currently does not support +				//e2_network_discovery(); +				#endif +			}  			else  				attach_one_net(name);  		} -  	} else {  		DBG(0, "unable to parse config line: %s\n", line);  	} @@ -564,13 +1849,16 @@ 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, V_MINOR, +		*version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR,  					  EPSONDS_BUILD);  	sanei_usb_init(); @@ -582,6 +1870,7 @@ void  sane_exit(void)  {  	DBG(5, "** %s\n", __func__); +	free_profile_maps(&stProfileMapArray);  	free_devices();  } @@ -591,7 +1880,8 @@ sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)  	int i;  	epsonds_device *dev; -	DBG(5, "** %s\n", __func__); +	DBG(5, "** %s  local_only = %d \n", __func__, local_only); +  	probe_devices(local_only); @@ -612,12 +1902,14 @@ sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only)  	*device_list = devlist; +  	return SANE_STATUS_GOOD;  }  static SANE_Status  init_options(epsonds_scanner *s)  { +	DBG(5, "init_options\n");  	int i;  	for (i = 0; i < NUM_OPTIONS; i++) { @@ -632,11 +1924,11 @@ init_options(epsonds_scanner *s)  	s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;  	/* "Scan Mode" group: */ - -	s->opt[OPT_MODE_GROUP].title = SANE_I18N("Scan Mode"); -	s->opt[OPT_MODE_GROUP].desc = ""; -	s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; -	s->opt[OPT_MODE_GROUP].cap = 0; +	s->opt[OPT_STANDARD_GROUP].name = SANE_NAME_STANDARD; +	s->opt[OPT_STANDARD_GROUP].title = SANE_TITLE_STANDARD; +	s->opt[OPT_STANDARD_GROUP].desc = SANE_DESC_STANDARD; +	s->opt[OPT_STANDARD_GROUP].type = SANE_TYPE_GROUP; +	s->opt[OPT_STANDARD_GROUP].cap = 0;  	/* scan mode */  	s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; @@ -761,18 +2053,6 @@ init_options(epsonds_scanner *s)  	if (!s->hw->adf_has_load)  		s->opt[OPT_LOAD].cap |= SANE_CAP_INACTIVE; -	s->opt[OPT_ADF_MODE].name = "adf-mode"; -	s->opt[OPT_ADF_MODE].title = SANE_I18N("ADF Mode"); -	s->opt[OPT_ADF_MODE].desc = -		SANE_I18N("Selects the ADF mode (simplex/duplex)"); -	s->opt[OPT_ADF_MODE].type = SANE_TYPE_STRING; -	s->opt[OPT_ADF_MODE].size = max_string_size(adf_mode_list); -	s->opt[OPT_ADF_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; -	s->opt[OPT_ADF_MODE].constraint.string_list = adf_mode_list; -	s->val[OPT_ADF_MODE].w = 0; /* simplex */ - -	if (!s->hw->adf_is_duplex) -		s->opt[OPT_ADF_MODE].cap |= SANE_CAP_INACTIVE;  	s->opt[OPT_ADF_SKEW].name = "adf-skew";  	s->opt[OPT_ADF_SKEW].title = SANE_I18N("ADF Skew Correction"); @@ -781,8 +2061,26 @@ init_options(epsonds_scanner *s)  	s->opt[OPT_ADF_SKEW].type = SANE_TYPE_BOOL;  	s->val[OPT_ADF_SKEW].w = 0; + +	s->opt[OPT_ADF_CRP].name = "adf-crp"; +	s->opt[OPT_ADF_CRP].title = SANE_I18N("ADF CRP Correction"); +	s->opt[OPT_ADF_CRP].desc = +		SANE_I18N("Enables ADF auto cropping"); // +	s->opt[OPT_ADF_CRP].type = SANE_TYPE_BOOL; +	s->val[OPT_ADF_CRP].w = 0; + +  	if (!s->hw->adf_has_skew) +	{ +		s->val[OPT_ADF_SKEW].w = 0;  		s->opt[OPT_ADF_SKEW].cap |= SANE_CAP_INACTIVE; +	} + +	if(!s->hw->adf_has_crp) +	{ +		s->val[OPT_ADF_CRP].w = 0; +		s->opt[OPT_ADF_CRP].cap |= SANE_CAP_INACTIVE; +	}  	return SANE_STATUS_GOOD;  } @@ -793,6 +2091,8 @@ sane_open(SANE_String_Const name, SANE_Handle *handle)  	SANE_Status status;  	epsonds_scanner *s = NULL; + +  	DBG(7, "** %s: name = '%s'\n", __func__, name);  	/* probe if empty device name provided */ @@ -848,6 +2148,8 @@ sane_open(SANE_String_Const name, SANE_Handle *handle)  		status = eds_lock(s);  	} +	setvalue((SANE_Handle)s, OPT_MODE, (void*)SANE_VALUE_SCAN_MODE_COLOR, NULL); +  	return status;  } @@ -881,24 +2183,6 @@ search_string_list(const SANE_String_Const *list, SANE_String value)  	return ((*list == NULL) ? NULL : list);  } -static void -activateOption(epsonds_scanner *s, SANE_Int option, SANE_Bool *change) -{ -	if (!SANE_OPTION_IS_ACTIVE(s->opt[option].cap)) { -		s->opt[option].cap &= ~SANE_CAP_INACTIVE; -		*change = SANE_TRUE; -	} -} - -static void -deactivateOption(epsonds_scanner *s, SANE_Int option, SANE_Bool *change) -{ -	if (SANE_OPTION_IS_ACTIVE(s->opt[option].cap)) { -		s->opt[option].cap |= SANE_CAP_INACTIVE; -		*change = SANE_TRUE; -	} -} -  /*   * Handles setting the source (flatbed, transparency adapter (TPU),   * or auto document feeder (ADF)). @@ -911,7 +2195,6 @@ static void  change_source(epsonds_scanner *s, SANE_Int optindex, char *value)  {  	int force_max = SANE_FALSE; -	SANE_Bool dummy;  	DBG(1, "%s: optindex = %d, source = '%s'\n", __func__, optindex,  	    value); @@ -928,26 +2211,17 @@ change_source(epsonds_scanner *s, SANE_Int optindex, char *value)  		force_max = SANE_TRUE;  	} -	if (strcmp(ADF_STR, value) == 0) { - +	if (strcmp(STRING_ADFFRONT, value) == 0 || strcmp(STRING_ADFDUPLEX, value) == 0) {  		s->hw->x_range = &s->hw->adf_x_range;  		s->hw->y_range = &s->hw->adf_y_range;  		s->hw->alignment = s->hw->adf_alignment; -		if (s->hw->adf_is_duplex) { -			activateOption(s, OPT_ADF_MODE, &dummy); -		} else { -			deactivateOption(s, OPT_ADF_MODE, &dummy); -			s->val[OPT_ADF_MODE].w = 0; -		}  	} else if (strcmp(TPU_STR, value) == 0) {  		s->hw->x_range = &s->hw->tpu_x_range;  		s->hw->y_range = &s->hw->tpu_y_range; -		deactivateOption(s, OPT_ADF_MODE, &dummy); -  	} else {  		/* neither ADF nor TPU active, assume FB */ @@ -995,7 +2269,6 @@ getvalue(SANE_Handle handle, SANE_Int option, void *value)  		break;  	case OPT_MODE: -	case OPT_ADF_MODE:  	case OPT_SOURCE:  		strcpy((char *) value, sopt->constraint.string_list[sval->w]);  		break; @@ -1045,12 +2318,9 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)  	switch (option) { -	case OPT_ADF_MODE: /* simple lists */ -		sval->w = optindex; -		break; -  	case OPT_ADF_SKEW:  	case OPT_RESOLUTION: +	case OPT_ADF_CRP:  		sval->w = *((SANE_Word *) value);  		reload = SANE_TRUE;  		break; @@ -1064,9 +2334,29 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)  		// fall through  	case OPT_TL_X:  	case OPT_TL_Y: +  		sval->w = *((SANE_Word *) value);  		if (NULL != info)  			*info |= SANE_INFO_RELOAD_PARAMS; + +		if (option == OPT_BR_X) +		{ +			DBG(17, "OPT_BR_X = %d\n", sval->w); +		} +		if (option == OPT_BR_Y) +		{ +			DBG(17, "OPT_BR_Y = %d\n", sval->w); +		} +		if (option == OPT_TL_X) +		{ +			DBG(17, "OPT_TL_X = %d\n", sval->w); +		} +		if (option == OPT_TL_Y) +		{ +			DBG(17, "OPT_TL_Y = %d\n", sval->w); +		} +		// adf crop set to off +		s->val[OPT_ADF_CRP].w = 0;  		break;  	case OPT_SOURCE: @@ -1076,6 +2366,8 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)  	case OPT_MODE:  	{ +		DBG(17, " OPT_MODE = index %d\n", optindex); +  		/* use JPEG mode if RAW is not available when bpp > 1 */  		if (optindex > 0 && !s->hw->has_raw) {  			s->mode_jpeg = 1; @@ -1152,6 +2444,183 @@ sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action,  	return SANE_STATUS_INVAL;  } + +static void setBit (SANE_Byte* bytes, SANE_Int bitIndex, SANE_Bool isTrue) +{ +    SANE_Int octet = bitIndex / 8; +    SANE_Byte  bit   = 7 - (bitIndex % 8); + +    if (isTrue) { +        bytes[octet] |=  (1 << bit); +    } else { +        bytes[octet] &= ~(1 << bit); +    } +} + +static SANE_Bool getBit (SANE_Byte* bytes, SANE_Int bitIndex) +{ +    SANE_Int octet = bitIndex / 8; +    SANE_Byte mask = 1 << (7 - (bitIndex % 8)); + +    if( bytes[octet] & mask ){ +        return SANE_TRUE; +    } + +    return SANE_FALSE; +} + +static void swapPixel1(SANE_Int  x1, +                       SANE_Int  y1, +                       SANE_Int  x2, +                       SANE_Int  y2, +                       SANE_Byte*  bytes, +                       SANE_Byte   bitsPerSample, +                       SANE_Int  samplesPerPixel, +                       SANE_Int  bytesPerRow) +{ +    SANE_Int pixelBits =  bitsPerSample * samplesPerPixel; +    SANE_Int widthBits =  bytesPerRow * 8; + +    SANE_Byte temp = getBit(bytes, widthBits * y1 + x1 * pixelBits); +    { +        SANE_Byte right =  getBit(bytes, widthBits * y2 + x2 * pixelBits); +        setBit(bytes, widthBits * y1 + x1 * pixelBits, right); +    } +    setBit(bytes, widthBits * y2 + x2 * pixelBits, temp); +} + +static void swapPixel8(SANE_Int  x1, +                       SANE_Int  y1, +                       SANE_Int  x2, +                       SANE_Int  y2, +                       SANE_Byte*  bytes, +                       SANE_Byte   bitsPerSample, +                       SANE_Int  samplesPerPixel, +                       SANE_Int  bytesPerRow) +{ +    SANE_Int pixelBytes =  samplesPerPixel * bitsPerSample / 8; + +    for (SANE_Byte i = 0; i < pixelBytes; i++) { +        SANE_Byte temp = bytes[y1 * bytesPerRow +  (pixelBytes *  x1 + i)]; +        bytes[y1 * bytesPerRow + (pixelBytes * x1 + i)] =  bytes[y2 * bytesPerRow +  (pixelBytes * x2 + i)]; +        bytes[y2 * bytesPerRow + (pixelBytes * x2 + i)] =  temp; +    } +} + + + +static void swapPixel(SANE_Int  x1, +                      SANE_Int  y1, +                      SANE_Int  x2, +                      SANE_Int  y2, +                      SANE_Byte*  bytes, +                      SANE_Byte   bitsPerSample, +                      SANE_Int  samplesPerPixel, +                      SANE_Int  bytesPerRow) +{ +    if (bitsPerSample == 1) { +        swapPixel1(x1, y1, x2, y2, bytes, bitsPerSample, samplesPerPixel, bytesPerRow); +    }else if(bitsPerSample == 8 || bitsPerSample == 16){ +        swapPixel8(x1, y1, x2, y2, bytes, bitsPerSample, samplesPerPixel, bytesPerRow); +    } +} + + +void +upside_down_backside_image(epsonds_scanner *s) +{ +	// get all data from ring_buffer +	if (eds_ring_avail(&s->back)  && +	    (strcmp(s->hw->sane.model, (char*)"DS-1630") == 0 +		 || strcmp(s->hw->sane.model, (char*)"DS-1610") == 0 +		 || strcmp(s->hw->sane.model, (char*)"DS-1660W") == 0)) +	{ +		SANE_Int bytesPerLine = s->params.bytes_per_line; +		SANE_Int imageSize = bytesPerLine * s->height_back; + +		SANE_Byte* workBuffer = malloc(imageSize); +		// if there is not enough memory, do nothing. +		if (workBuffer) +		{ +			eds_ring_read(&s->back, workBuffer, imageSize); +			SANE_Int  samplesPerPxel = 3; +			if (s->params.format == SANE_FRAME_RGB) +			{ +				samplesPerPxel = 3; +			} +			else if (s->params.format == SANE_FRAME_GRAY) +			{ +				samplesPerPxel = 1; +			} + +			SANE_Int half = (s->height_back / 2) - 1; +			if (half < 0) { +				half = 0; +			} + +			if((s->height_back % 2) == 1) { +				SANE_Int ymid = ( (s->height_back - 1 ) / 2 ); +				for(SANE_Int x = 0;x < (s->width_back / 2); x++) { +					swapPixel(x, ymid, s->width_back - x - 1, ymid, workBuffer, s->params.depth, samplesPerPxel, s->params.bytes_per_line); +				} +			} + +			if (s->height_back != 1) { +				for(SANE_Int x = 0; x < s->width_back; x++) { +					for(SANE_Int y = 0;y <= half; y++) { +						swapPixel(x, y, s->width_back - x - 1, s->height_back - y -1, workBuffer, s->params.depth, samplesPerPxel, s->params.bytes_per_line); +					} +				} +			} + +			eds_ring_write(&s->back, workBuffer, imageSize); +			free(workBuffer); +			workBuffer = NULL; + +		} +	} + +} + + +SANE_Status +get_next_image(epsonds_scanner *s) +{ +	SANE_Status status = SANE_STATUS_GOOD; + +	if (s->acquirePage == 0 && s->current == &s->front) +	{ +		DBG(20, "** %s:  get_next_image\n", __func__); + + +		/*page info will be updatted by pen*/ +		s->width_back = 0; +		s->width_front = 0; +		s->height_back = 0; +		s->height_front = 0; + +		if (s->mode_jpeg) +		{ +			status = acquire_and_decode_jpeg_data(s); +		}else{ +			status = acquire_raw_data(s); +		} +		if (status != SANE_STATUS_GOOD) +		{ +			eds_ring_flush(&s->front); +			eds_ring_flush(&s->back); +			eds_ring_destory(&s->front); +			eds_ring_destory(&s->back); +		} +		DBG(20," ringFront = %d ringBack = %d\n", eds_ring_avail(&s->front), eds_ring_avail(&s->back)); + +		s->acquirePage = 1; +	} + +	return status; +} + +  SANE_Status  sane_get_parameters(SANE_Handle handle, SANE_Parameters *params)  { @@ -1173,25 +2642,186 @@ sane_get_parameters(SANE_Handle handle, SANE_Parameters *params)  		eds_init_parameters(s);  	} + +	SANE_Status status = SANE_STATUS_GOOD; + +	status = get_next_image(s); + +	// if size auto, update page size value +	if(s->val[OPT_ADF_CRP].w) +	{ +		// frontside +		if (s->current == &s->front) +		{ +			DBG(20, "front side \n"); +			if (s->width_front != 0 && s->height_front != 0) +			{ +				if (s->params.format == SANE_FRAME_RGB) +				{ +					s->params.bytes_per_line = s->width_front * 3; +					s->params.pixels_per_line = s->width_front; +				} + +				if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8) +				{ +					s->params.bytes_per_line = s->width_front; +					s->params.pixels_per_line = s->width_front; +				} + +				if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1) +				{ +					s->params.bytes_per_line = (s->width_front + 7)/8; +					s->params.pixels_per_line = s->width_front; +				} +				s->params.lines = s->height_front; +			} +		} +		// backside +		if (s->current == &s->back) +		{ +			DBG(20, "back side \n"); +			if (s->width_back != 0 && s->height_back != 0) +			{ +				if (s->params.format == SANE_FRAME_RGB) +				{ +					s->params.bytes_per_line = s->width_back * 3; +					s->params.pixels_per_line = s->width_back; +				} + +				if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8) +				{ +					s->params.bytes_per_line = s->width_back; +					s->params.pixels_per_line = s->width_back; +				} + +				if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1) +				{ +					s->params.bytes_per_line = (s->width_back + 7)/8; +					s->params.pixels_per_line = s->width_back; +				} +				s->params.lines = s->height_back; +			} +		} +	}  	if (params != NULL)  		*params = s->params;  	print_params(s->params); -	return SANE_STATUS_GOOD; +	DBG(20, "s->params.line  = %d  s->params.bytes_per_line = %d s->params.pixels_per_line = %d \n", s->params.lines, s->params.bytes_per_line , s->params.pixels_per_line ); +	return status; +} + + + +typedef float ColorMatrix[3][3]; + +#define CCT_TABLE_SIZE 9 +static int get_roundup_index(double frac[], int n) +{ +    int        i, index = -1; +    double    max_val = 0.0; + +    for (i=0; i<n; i++) { +        if (frac[i]<0) continue; +        if (max_val<frac[i]) { +            index = i; +            max_val = frac[i]; +        } +    } +    return index; +} + +static int get_rounddown_index(double frac[], int n) +{ +    int        i, index = -1; +    double    min_val  = 1.0; + +    for (i=0; i<n; i++) { +        if (frac[i]>0) continue; +        if (min_val>frac[i]) { +            index = i; +            min_val = frac[i]; +        } +    } +    return index;  } + +void ESCIRoundColorCorrectionMatrix(int mult, double org_cct[], int rnd_cct[]) +{ +    int        i, j, index; +    double    mult_cct[CCT_TABLE_SIZE], frac[CCT_TABLE_SIZE]; +    int        sum[3]; +    int        loop; + +    for (i=0; i<CCT_TABLE_SIZE; i++) { +        mult_cct[i] = org_cct[i] * mult; +    } + +    // round value multiplied by 'mult' off to integer. +    for (i=0; i<CCT_TABLE_SIZE; i++) { +        rnd_cct[i] = (int)floor(org_cct[i] * mult + 0.5); +    } + +    loop=0; +    do { +        // If all element equal to 11, diagonal element is set to 10. +        for (i=0; i<3; i++) { +            if (    (rnd_cct[i*3]==11) && +                (rnd_cct[i*3]==rnd_cct[i*3+1]) && +                (rnd_cct[i*3]==rnd_cct[i*3+2])    ) { +                rnd_cct[i*3+i] --; +                mult_cct[i*3+i] = rnd_cct[i*3+i]; +            } +        } +        // calc. summation of each line. +        for (i=0; i<3; i++) { +            sum[i] = 0; +            for (j=0; j<3; j++) { +                sum[i] += rnd_cct[i*3+j]; +            } +        } +        // calc. values rounded up or down. +        for (i=0; i<CCT_TABLE_SIZE; i++) { +            frac[i] = mult_cct[i] - rnd_cct[i]; +        } + +        // if summation does not equal to 'mult', adjust rounded up or down value. +        for (i=0; i<3; i++) { +            if (sum[i]<mult) { +                index = get_roundup_index(&frac[i*3], 3); +                if (index!=-1) { +                    rnd_cct[i*3+index] ++; +                    mult_cct[i*3+index] = rnd_cct[i*3+index]; +                    sum[i]++; +                } +            } else if (sum[i]>mult) { +                index = get_rounddown_index(&frac[i*3], 3); +                if (index!=-1) { +                    rnd_cct[i*3+index] --; +                    mult_cct[i*3+index] = rnd_cct[i*3+index]; +                    sum[i]--; +                } +            } +        } + +    } while ((++loop<2)&&((sum[0]!=mult)||(sum[1]!=mult)||(sum[2]!=mult))); +} + + +  /*   * This function is part of the SANE API and gets called from the front end to   * start the scan process.   */ - +#define CMD_BUF_SIZE 1000  SANE_Status  sane_start(SANE_Handle handle)  {  	epsonds_scanner *s = (epsonds_scanner *)handle;  	char buf[65]; /* add one more byte to correct buffer overflow issue */ -	char cmd[100]; /* take care not to overflow */ +	char cmd[CMD_BUF_SIZE]; /* take care not to overflow */  	SANE_Status status = 0;  	s->pages++; @@ -1203,26 +2833,28 @@ sane_start(SANE_Handle handle)  	s->eof = 0;  	s->canceling = 0; +	s->acquirePage = 0;  	if ((s->pages % 2) == 1) {  		s->current = &s->front; -		eds_ring_flush(s->current);  	} else if (eds_ring_avail(&s->back)) {  		DBG(5, "back side\n");  		s->current = &s->back;  	} -	/* prepare the JPEG decompressor */ -	if (s->mode_jpeg) { -		status = eds_jpeg_start(s); -		if (status != SANE_STATUS_GOOD) { -			goto end; -	}	} -  	/* scan already in progress? (one pass adf) */ -	if (s->scanning) { +	if (s->scanning  || eds_ring_avail(&s->back) > 0) {  		DBG(5, " scan in progress, returning early\n"); -		return SANE_STATUS_GOOD; +		return get_next_image(s); +	} +	if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) { +		if (s->scanEnd) +		{ +	  		 s->scanEnd = 0; +	  		 return SANE_STATUS_NO_DOCS; +		} +	}else{ +	   s->scanEnd = 0;  	}  	/* calc scanning parameters */ @@ -1239,13 +2871,7 @@ sane_start(SANE_Handle handle)  	/* transfer buffer size, bsz */  	/* XXX read value from scanner */ -	s->bsz = (65536 * 4); - -	/* ring buffer for front page */ -	status = eds_ring_init(&s->front, s->bsz * 2); -	if (status != SANE_STATUS_GOOD) { -		return status; -	} +	s->bsz = (1048576 * 4);  	/* transfer buffer */  	s->buf = realloc(s->buf, s->bsz); @@ -1256,29 +2882,34 @@ sane_start(SANE_Handle handle)  	/* set scanning parameters */ +	s->isDuplexScan = 0;  	/* document source */ -	if (strcmp(source_list[s->val[OPT_SOURCE].w], ADF_STR) == 0) { +	if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) { -		sprintf(buf, "#ADF%s%s", -			s->val[OPT_ADF_MODE].w ? "DPLX" : "", -			s->val[OPT_ADF_SKEW].w ? "SKEW" : ""); +		SANE_Int status = esci2_stat(s); +		if (status == SANE_STATUS_NO_DOCS) +		{ +		   return SANE_STATUS_NO_DOCS; +		} -		/* it seems that DFL only works in duplex mode, but it's -		 * also required to be enabled or duplex will be rejected. -		 */ +		SANE_Int duplexMode = (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0); -		if (s->val[OPT_ADF_MODE].w) { +		sprintf(buf, "#ADF%s%s%s", +		duplexMode ? "DPLX" : "", +		s->val[OPT_ADF_SKEW].w ? "SKEW" : "", +		s->val[OPT_ADF_CRP].w ? "CRP " : "" +		); -			if (s->hw->adf_has_dfd == 2) { -				strcat(buf, "DFL2"); -			} else if (s->hw->adf_has_dfd == 1) { -				strcat(buf, "DFL1"); -			} +		if (duplexMode) +		{ +			s->isDuplexScan = 1;  		} - -	} else if (strcmp(source_list[s->val[OPT_SOURCE].w], FBF_STR) == 0) { +		s->isflatbedScan = 0; +	} +	else if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_FLATBED) == 0) {  		strcpy(buf, "#FB "); +		s->isflatbedScan = 1;  	} else {  		/* XXX */ @@ -1286,8 +2917,18 @@ sane_start(SANE_Handle handle)  	strcpy(cmd, buf); +	s->needToConvertBW = 0; +  	if (s->params.format == SANE_FRAME_GRAY) { -		sprintf(buf, "#COLM%03d", s->params.depth); +		if (s->params.depth == 1 && s->hw->has_mono == 0) +		{ +			sprintf(buf, "#COLM008"); +			s->needToConvertBW = 1; +			s->mode_jpeg = 1; +		}else +		{ +			sprintf(buf, "#COLM%03d", s->params.depth); +		}  	} else if (s->params.format == SANE_FRAME_RGB) {  		sprintf(buf, "#COLC%03d", s->params.depth * 3);  	} @@ -1303,9 +2944,29 @@ sane_start(SANE_Handle handle)  		strcat(cmd, "#FMTJPG #JPGd090");  	} +	/* set GMM */ +	if (s->params.depth == 1) +	{ +		sprintf(buf, "#GMMUG10"); +	} else +	{ +		sprintf(buf, "#GMMUG18"); +	} +	strcat(cmd, buf); +  	/* resolution (RSMi not always supported) */ -	if (s->val[OPT_RESOLUTION].w > 999) { +	if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 && s->val[OPT_RESOLUTION].w > 600) { +		DBG(0, "Automatic Document Feeder supported resolution of 600dpi or less. \n"); +	} else if (s->val[OPT_RESOLUTION].w > 999) { +		sprintf(buf, "#RSMi%07d#RSSi%07d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w); +	} else { +		sprintf(buf, "#RSMd%03d#RSSd%03d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w); +	} + +		if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0 && s->val[OPT_RESOLUTION].w > 600) { +		DBG(0, "Automatic Document Feeder supported resolution of 600dpi or less. \n"); +	} else if (s->val[OPT_RESOLUTION].w > 999) {  		sprintf(buf, "#RSMi%07d#RSSi%07d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w);  	} else {  		sprintf(buf, "#RSMd%03d#RSSd%03d", s->val[OPT_RESOLUTION].w, s->val[OPT_RESOLUTION].w); @@ -1313,13 +2974,321 @@ sane_start(SANE_Handle handle)  	strcat(cmd, buf); +	if (strcmp(s->hw->sane.model, (char*)"DS-70") == 0 || strcmp(s->hw->sane.model, (char*)"ES-65WR") == 0 || strcmp(s->hw->sane.model, (char*)"ES-60W") == 0 +	|| strcmp(s->hw->sane.model, (char*)"DS-80W") == 0 || strcmp(s->hw->sane.model, (char*)"ES-55R") == 0 || strcmp(s->hw->sane.model, (char*)"ES-50") == 0){ +		sprintf(buf, "#BSZi0262144"); +		strcat(cmd, buf); +	} +	else { +		sprintf(buf, "#BSZi1048576"); +		strcat(cmd, buf); +	} + +  	/* scanning area */ +  	sprintf(buf, "#ACQi%07di%07di%07di%07d",  		s->left, s->top, s->params.pixels_per_line, s->params.lines); + +	if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) { +		status = esci2_stat(s); +		if (status != SANE_STATUS_GOOD) { +			goto end; +		} +	} +  	strcat(cmd, buf); -	status = esci2_para(s, cmd); + +	int pos = 0; + +	{ +		for (int i = 0; i < CMD_BUF_SIZE; i++) +		{ +			// find end of string +			if(cmd[i] == 0) +			{ +				pos = i; +				break; +			} +		} + + +		if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 8) { +			DBG(10, "SANE_FRAME_GRAY\n"); +			cmd[pos++] = '#'; +			cmd[pos++] = 'G'; +			cmd[pos++] = 'M'; +			cmd[pos++] = 'T'; +			cmd[pos++] = 'M'; +			cmd[pos++] = 'O'; +			cmd[pos++] = 'N'; +			cmd[pos++] = 'O'; +			cmd[pos++] = 'h'; +			cmd[pos++] = '1'; +			cmd[pos++] = '0'; +			cmd[pos++] = '0'; + +			for(int count = 0; count < 256; count++) { +				cmd[pos++] =  LUT[s->hw->lut_id][count]; +			} +		} +		if (s->params.format == SANE_FRAME_GRAY && s->params.depth == 1) { +			DBG(10, "SANE_FRAME_GRAY\n"); +			cmd[pos++] = '#'; +			cmd[pos++] = 'G'; +			cmd[pos++] = 'M'; +			cmd[pos++] = 'T'; +			cmd[pos++] = 'M'; +			cmd[pos++] = 'O'; +			cmd[pos++] = 'N'; +			cmd[pos++] = 'O'; +			cmd[pos++] = 'h'; +			cmd[pos++] = '1'; +			cmd[pos++] = '0'; +			cmd[pos++] = '0'; + +			for(int count = 0; count < 256; count++) { +				cmd[pos++] =  LUT[0][count]; +			} +		} +		else if (s->params.format == SANE_FRAME_RGB) { +			DBG(10, "SANE_FRAME_RGB\n"); +			cmd[pos++] = '#'; +			cmd[pos++] = 'G'; +			cmd[pos++] = 'M'; +			cmd[pos++] = 'T'; +			cmd[pos++] = 'R'; +			cmd[pos++] = 'E'; +			cmd[pos++] = 'D'; +			cmd[pos++] = ' '; +			cmd[pos++] = 'h'; +			cmd[pos++] = '1'; +			cmd[pos++] = '0'; +			cmd[pos++] = '0'; + +			for(int count = 0; count < 256; count++) { +				cmd[pos++] =  LUT_R[s->hw->lut_id][count]; +			} + +			cmd[pos++] = '#'; +			cmd[pos++] = 'G'; +			cmd[pos++] = 'M'; +			cmd[pos++] = 'T'; +			cmd[pos++] = 'G'; +			cmd[pos++] = 'R'; +			cmd[pos++] = 'N'; +			cmd[pos++] = ' '; +			cmd[pos++] = 'h'; +			cmd[pos++] = '1'; +			cmd[pos++] = '0'; +			cmd[pos++] = '0'; + +			for(int count = 0; count < 256; count++) { +				cmd[pos++] =  LUT_G[s->hw->lut_id][count]; +			} + +			cmd[pos++] = '#'; +			cmd[pos++] = 'G'; +			cmd[pos++] = 'M'; +			cmd[pos++] = 'T'; +			cmd[pos++] = 'B'; +			cmd[pos++] = 'L'; +			cmd[pos++] = 'U'; +			cmd[pos++] = ' '; +			cmd[pos++] = 'h'; +			cmd[pos++] = '1'; +			cmd[pos++] = '0'; +			cmd[pos++] = '0'; + +			for(int count = 0; count < 256; count++) { +				cmd[pos++] =  LUT_B[s->hw->lut_id][count]; +			} +		} +		cmd[pos] = 0; + +	} +	{// Set Color Matrix +		if (s->params.format == SANE_FRAME_RGB && s->hw->lut_id != 0 )/*Color Matrix Target devide and color Scan*/ +		{ +			ColorMatrix matrix; + +			// DS-530 + +			if (s->hw->lut_id == 2) +			{ +				// R +				matrix[0][0] = 1.0229; +				matrix[0][1] = 0.0009; +				matrix[0][2] = -0.0238; + +				// G +				matrix[1][0] = 0.0031; +				matrix[1][1] = 1.0287; +				matrix[1][2] = -0.0318; + +				//B +				matrix[2][0] = 0.0044; +				matrix[2][1] = -0.1150; +				matrix[2][2] = 1.1106; +			} + +			// DS-1660W Flatbed + +			if (s->hw->lut_id == 4) +			{ +				// R +				matrix[0][0] = 1.0229; +				matrix[0][1] = 0.0009; +				matrix[0][2] = -0.0238; + +				// G +				matrix[1][0] = 0.0031; +				matrix[1][1] = 1.0287; +				matrix[1][2] = -0.0318; + +				//B +				matrix[2][0] = 0.0044; +				matrix[2][1] = -0.1150; +				matrix[2][2] = 1.1106; +			} + + +			// DS-320 + +			if (s->hw->lut_id == 5) +			{ +				// R +				matrix[0][0] = 1.0250; +				matrix[0][1] = 0.0004; +				matrix[0][2] = -0.0254; + +				// G +				matrix[1][0] = 0.0003; +				matrix[1][1] = 1.0022; +				matrix[1][2] = -0.0025; + +				//B +				matrix[2][0] = 0.0049; +				matrix[2][1] = -0.0949; +				matrix[2][2] = 1.0900; +			} + + +			// ES-50 + +			if (s->hw->lut_id == 6) +			{ +				// R +				matrix[0][0] = 1.0383; +				matrix[0][1] = -0.0021; +				matrix[0][2] = -0.0362; + +				// G +				matrix[1][0] = 0.0046; +				matrix[1][1] = 1.0576; +				matrix[1][2] = -0.0622; + +				//B +				matrix[2][0] = 0.0235; +				matrix[2][1] = -0.2396; +				matrix[2][2] = 1.2161; +			} + + +			// R +			matrix[0][0] = 0.9864; +			matrix[0][1] = 0.0248; +			matrix[0][2] = -0.0112; + +			// G +			matrix[1][0] = 0.0021; +			matrix[1][1] = 1.0100; +			matrix[1][2] = -0.0112; + +			//B +			matrix[2][0] = 0.0139; +			matrix[2][1] = -0.1249; +			matrix[2][2] = 1.1110; + + +			// Set Matrix value +			{ +				cmd[pos++] = '#'; +				cmd[pos++] = 'C'; +				cmd[pos++] = 'M'; +				cmd[pos++] = 'X'; +				cmd[pos++] = 'U'; +				cmd[pos++] = 'M'; +				cmd[pos++] = '0'; +				cmd[pos++] = '8'; +				cmd[pos++] = 'h'; +				cmd[pos++] = '0'; +				cmd[pos++] = '0'; +				cmd[pos++] = '9'; +			} + + +			// Matrix to be sent to scanner must be following d1-d9 order: +			// +			//     G  R  B +			// G [d1 d4 d7] +			// R [d2 d5 d8] +			// B [d3 d6 d9] +			// +			// So, we will convert it with index table. +			char index[9] = {4, 1, 7, 3, 0, 6, 5, 2, 8}; + +			double flatten[9] = {0}; +			for (int row = 0; row < 3; row++) { +				for (int col = 0; col < 3; col++) { +					flatten[row * 3 + col] = matrix[row][col]; +				} +			} + +			int rounded[9] = {0}; +			ESCIRoundColorCorrectionMatrix(32, flatten, rounded); + + +			char ordered[9] = {0}; +			for (int row = 0; row < 3; row++) { +				for (int col = 0; col < 3; col++) { +					int val = rounded[row * 3 + col]; +					unsigned char oct = (unsigned char)abs(val); +					oct |= ((val < 0) ? (1 << 7) : 0); +					ordered[(signed char)index[row * 3 + col]] = oct; +				} +			} +			{ +				cmd[pos++] = ordered[0]; +				cmd[pos++] = ordered[1]; +				cmd[pos++] = ordered[2]; +				cmd[pos++] = ordered[3]; +				cmd[pos++] = ordered[4]; +				cmd[pos++] = ordered[5]; +				cmd[pos++] = ordered[6]; +				cmd[pos++] = ordered[7]; +				cmd[pos++] = ordered[8]; +				cmd[pos++] = 0; //padding + 				cmd[pos++] = 0; //padding +				cmd[pos++] = 0; //padding + + +				DBG(1, "color matrix\n"); +				for (int i = 0; i < 9; i++) +				{ +					DBG(1, "%d\n", ordered[i]); +				} + +			} +			cmd[pos] = 0; +		} + +	} + + +	status = esci2_para(s, cmd, pos);  	if (status != SANE_STATUS_GOOD) {  		goto end;  	} @@ -1336,7 +3305,8 @@ sane_start(SANE_Handle handle)  	/* first page is page 1 */  	s->pages = 1;  	s->scanning = 1; - +	s->dummy = 0; +	s->scanEnd = 0;  end:  	if (status != SANE_STATUS_GOOD) {  		DBG(1, "%s: start failed: %s\n", __func__, sane_strstatus(status)); @@ -1345,140 +3315,305 @@ end:  	return status;  } -/* this moves data from our buffers to SANE */ - -SANE_Status -sane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length, -	  SANE_Int *length) +static SANE_Status acquire_jpeg_data(epsonds_scanner* s)  { -	SANE_Int read = 0, tries = 3; -	SANE_Int available; -	SANE_Status status = 0; -	epsonds_scanner *s = (epsonds_scanner *)handle; -	*length = read = 0; +	SANE_Int read = 0; -	DBG(20, "** %s: backside = %d\n", __func__, s->backside); - -	/* sane_read called before sane_start? */ -	if (s->current == NULL) { -		DBG(0, "%s: buffer is NULL", __func__); -		return SANE_STATUS_INVAL; +	SANE_Int jpegBufSize = s->params.bytes_per_line * s->params.lines; +	if (s->needToConvertBW) +	{ +		jpegBufSize = s->params.pixels_per_line * s->params.lines;  	} -	/* anything in the buffer? pass it to the frontend */ -	available = eds_ring_avail(s->current); -	if (available) { -		DBG(18, "reading from ring buffer, %d left\n", available); +	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; -		if (s->mode_jpeg && !s->jpeg_header_seen) { +	int eofFront = 0; +	int eofBack = 0; -			status = eds_jpeg_read_header(s); -			if (status != SANE_STATUS_GOOD && --tries) { -				goto read_again; + +	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) +		{ -		if (s->mode_jpeg) { -			eds_jpeg_read(handle, data, max_length, &read); -		} else { -			eds_copy_image_from_ring(s, data, max_length, &read); +			DBG(20, "continue acquire image\n"); +			continue;  		} - -		if (read == 0) { -			goto read_again; +		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;  		} -		*length = read; -		return SANE_STATUS_GOOD; +		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; +} -	} else if (s->current == &s->back) { +static SANE_Status +acquire_raw_data(epsonds_scanner* s) +{ +	SANE_Int read = 0; -		/* finished reading the back page, next -		 * command should give us the EOF -		 */ -		DBG(18, "back side ring buffer empty\n"); -	} +		// load all images, decode and fill buffer +	SANE_Int status = SANE_STATUS_GOOD; -	/* read until data or error */ +	int eofFront = 0; +	int eofBack = 0; +	int firstWrite = 1; -read_again: +	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; +			} -	status = esci2_img(s, &read); -	if (status != SANE_STATUS_GOOD) { -		DBG(20, "read: %d, eof: %d, backside: %d, status: %d\n", read, s->eof, s->backside, status); -	} +			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"); -	/* just got a back side page, alloc ring buffer if necessary -	 * we didn't before because dummy was not known -	 */ -	if (s->backside) { +		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; +		} -		int required = s->params.lines * (s->params.bytes_per_line + s->dummy); +		if (s->isDuplexScan) +		{ +			// acquire finish +			if (eofFront && eofBack) +			{ +				break; +			} +		}else{ +			if (eofFront) +			{ +				break; +			} +		} +	} -		if (s->back.size < required) { -			DBG(20, "allocating buffer for the back side\n"); +	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); -			status = eds_ring_init(&s->back, required); -			if (status != SANE_STATUS_GOOD) { -				return status; -			}  		} -	} -	/* abort scanning when appropriate */ -	if (status == SANE_STATUS_CANCELLED) { -		esci2_can(s); -		return status;  	} +	{ +		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->eof && s->backside) { -		DBG(18, "back side scan finished\n");  	} -	/* read again if no error and no data */ -	if (read == 0 && status == SANE_STATUS_GOOD) { -		goto read_again; +	if (s->isDuplexScan) +	{ +		upside_down_backside_image(s);  	} -	/* got something, write to ring */ -	if (read) { - -		DBG(20, " %d bytes read, %d lines, eof: %d, canceling: %d, status: %d, backside: %d\n", -			read, read / (s->params.bytes_per_line + s->dummy), -			s->canceling, s->eof, status, s->backside); +	DBG(20, "acquire_raw_data  finish"); +	return SANE_STATUS_GOOD; -		/* move data to the appropriate ring */ -		status = eds_ring_write(s->backside ? &s->back : &s->front, s->buf, read); +} -		if (0 && s->mode_jpeg && !s->jpeg_header_seen -			&& status == SANE_STATUS_GOOD) { +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; +			} -			status = eds_jpeg_read_header(s); -			if (status != SANE_STATUS_GOOD && --tries) { -				goto read_again; +			if (s->isDuplexScan) +			{ +				upside_down_backside_image(s);  			} +		}else{ +			DBG(20, "** %s:  sane finish status = %d\n", __func__, status); +			return status;  		} -	} - -	/* continue reading if appropriate */ -	if (status == SANE_STATUS_GOOD)  		return status; +} -	/* cleanup */ -	DBG(5, "** %s: cleaning up\n", __func__); +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->mode_jpeg) { -		eds_jpeg_finish(s); +	if (s->canceling) +	{ +		esci2_can(s); +		*length = 0; +		return SANE_STATUS_CANCELLED;  	} -	eds_ring_flush(s->current); +	int available = eds_ring_avail(s->current); +	/* anything in the buffer? pass it to the frontend */ +	if (available > 0) { -	return status; +		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; +	}  }  /* | 
