[sane-devel] add support for ricoh aficio sp100su

viruxx dj_virus142 at hotmail.com
Sun Mar 12 17:58:22 UTC 2017


ok the work is finished
i cleaned all the code, and removed things that was not usefull

for be short, this scanner support only 2 quality 300 dpi and 600 dpi
with 2 modes, color or grayscale, all the rest is software controlled

i sniffed the usb informations when resizing the scan area after a preview
totally useless : if we choose just a little area at the end of the A4 in
600 dpi,
the motor is going slow on the whole page, so i implemented nothing about it

i give you my driver in java :

> package me.virux;
> 
> import java.awt.Color;
> import java.awt.image.BufferedImage;
> import java.io.File;
> import java.io.IOException;
> import java.nio.ByteBuffer;
> import java.nio.ByteOrder;
> import java.nio.IntBuffer;
> import javax.imageio.ImageIO; 
> import org.usb4java.BufferUtils;
> import org.usb4java.Context;
> import org.usb4java.DeviceHandle;
> import org.usb4java.LibUsb;
> 
> public class AficioSP100su { 
> 	
> 	//variables can be changed by soft // default 300dpi, highquality =
> 600dpi
>  	static DeviceHandle usb; static int height = 3510; //height can be less
> if we want just a part of A4
>  	static String imageType = "png", filename="sexyFileName"; //b/w scan can
> be soft controlled only 
>  	static boolean color=false, black=false, cancel=false,
> highQuality=false;// here we got a 300dpi grayscale
>  	  
>  	static final short vendor = (short)0x05ca, product =
> (short)0x042c;//constants values
>  	static final byte urb_to = (byte) 0x03, urb_from = (byte) 0x85;
>  	
> 	public static void main(String[] args) throws IOException {  
> 		int width = 2560, packet = 61440; 
> 		if(highQuality){ width *= 2; height *= 2; }  
> 		int bytesToRead = width * height, totalBytesRead = 0; 
> 		if(color) bytesToRead *= 3; 
> 		 
> 		Context c = new Context();//start usb
> 		LibUsb.init(c);
> 		usb = LibUsb.openDeviceWithVidPid(c, vendor, product);
> 		LibUsb.claimInterface(usb, 0); 
> 		 
> 		send(new byte[]{0x03,0x09,0x01});    //start urb procedure
> 		read(1);
> 		send(new byte[]{0x03,0x0d,0x0b}); 
> 		read(11); 
> 		byte[] sequence = new
> byte[]{0x03,0x0c,0x11,0,0,0,0x01,0x02,0x05,0xffffffff,0,0,0,0,0xffffffec,0x13,0x6c,0x1b};
> 		if(highQuality)
> 			sequence[6]=0x02; 
> 		if(color)
> 			sequence[7]=0x03;
> 		send(sequence); 
> 		send(new byte[]{0x03,0x0b,0x08});
> 		read(8);
> 		send(new byte[]{0x03,0x08,0x04,0,0,0,0,0x50,0x6d,0x06,0x01});
> 		 
> 		//#######main loop
> 		ByteBuffer buffer = ByteBuffer.allocateDirect(bytesToRead);
>  		 	boolean loop = true; 
>  		 	while(loop){ 
>  		 		if(cancel)//soft can cancel the scan at every moment
>  		 			send(new byte[]{0x03,0x0a});  
>  		 		send(new byte[]{0x03, 0x0E, 0x04, 0,0,0,0,(byte) (packet/256) });
> //give me next packet pls 
> 			   
>  		 		buffer.put( read(packet) );
>  		 		totalBytesRead+=packet; 
> 			 
>  		 		if(totalBytesRead + packet >= bytesToRead){
>  		 			packet = bytesToRead - totalBytesRead;
>  		 			loop = false;
>  		 		}
>  		 		if(totalBytesRead + packet > bytesToRead || packet == 0) 
>  		 			loop = false;
>  		 	}//end of main loop
> 		 
> 		 send(new byte[]{0x03,0x0a}); //send cancel
> 		 send(new byte[]{0x03,0x09,0x01}); //send end 
> 		 read(1); //dont forget response
> 		
> 		 //no need usb anymore
> 		 LibUsb.releaseInterface(usb, 0);
> 		 LibUsb.close(usb);
> 		
> 		 
> 		//########## data interpretation 
> 		int passed = 0; BufferedImage img = null;
> 
> 		if(color){ //storage of aficio sp100 is 1 line = 1 color channel
> 			img = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
> 			
> 			for(int i = 0 ; i < totalBytesRead - (width * 3) ; i++ ){//loop the
> buffer until last line -2
> 				if(i % width == 0){ //if 1 complete width/line readed, jump over 2
> lines/width
> 					i += width * 2 ; 
> 					passed += width * 2 ; 
> 				}
> 				int r = buffer.get(i) & 0xFF;//first color is at current position
> 				int g = buffer.get(i + width) & 0xFF;//second color is at next
> line/width
> 				int b = buffer.get(i + width + width) & 0xFF;//3rd color is 2 lines
> after
> 				Color col = new Color( g,b,r ); //mix the 3 bytes in THIS order /!\
> 				img.setRGB( (i-passed) % width, (i-passed) / width, col.getRGB());
> //place pixel using line position
> 			}   
> 		}else{
> 			img = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY);
> 			
> 			if(black)//if black selected, software push it here
> 				img = new BufferedImage(width, height,
> BufferedImage.TYPE_BYTE_BINARY);
> 			
> 			for(int i = 0 ; i < totalBytesRead ; i++ ) {
> 				int gray = buffer.get(i) & 0xFF;
> 				img.setRGB(i % width, i / width, new Color(gray, gray, gray).getRGB()
> ); 
> 			}
> 		}
> 		ImageIO.write(img, imageType, new
> File(filename+"."+imageType.replaceAll("jpeg", "jpg")));   
> 	}//end of main program
> 	
> 
> //###########################################################################
> 	static void send(byte[] text) {  
> 		ByteBuffer buffer = ByteBuffer.allocateDirect( 64 ); 
> 		buffer.put(text);  
> 		LibUsb.bulkTransfer(usb, urb_to, buffer, IntBuffer.allocate(3), 20000); 
> 	}
> 	
> 
> //###########################################################################
> 	static ByteBuffer read(int size) {
> 		ByteBuffer buffer = BufferUtils.allocateByteBuffer(size).order(
> ByteOrder.LITTLE_ENDIAN); 
>         LibUsb.bulkTransfer(usb, urb_from, buffer, IntBuffer.allocate(3),
> 20000); 
>         return buffer;
>     }
> }





--
View this message in context: http://sane.10972.n7.nabble.com/add-support-for-ricoh-aficio-sp100su-tp20705p20718.html
Sent from the SANE - Dev mailing list archive at Nabble.com.



More information about the sane-devel mailing list