mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2024-11-27 12:49:35 +08:00
Fixed bugs in scrollview and upgraded piccolo to 3.0
git-svn-id: https://tesseract-ocr.googlecode.com/svn/trunk@1026 d0cd1f9f-072b-0410-8dd7-cf729c803f20
This commit is contained in:
parent
ad149844f0
commit
99e1f05952
@ -36,10 +36,10 @@ SCROLLVIEW_CLASSES = \
|
||||
com/google/scrollview/ScrollView.class
|
||||
|
||||
SCROLLVIEW_LIBS = \
|
||||
$(srcdir)/piccolo-1.2.jar \
|
||||
$(srcdir)/piccolox-1.2.jar
|
||||
$(srcdir)/piccolo2d-core-3.0.jar \
|
||||
$(srcdir)/piccolo2d-extras-3.0.jar
|
||||
|
||||
CLASSPATH = $(srcdir)/piccolo-1.2.jar:$(srcdir)/piccolox-1.2.jar
|
||||
CLASSPATH = $(srcdir)/piccolo2d-core-3.0.jar:$(srcdir)/piccolo2d-extras-3.0.jar
|
||||
|
||||
ScrollView.jar : $(SCROLLVIEW_CLASSES)
|
||||
$(JAR) cf $@ com/google/scrollview/*.class \
|
||||
|
@ -13,6 +13,7 @@ package com.google.scrollview;
|
||||
import com.google.scrollview.events.SVEvent;
|
||||
import com.google.scrollview.ui.SVImageHandler;
|
||||
import com.google.scrollview.ui.SVWindow;
|
||||
import org.piccolo2d.nodes.PImage;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@ -23,7 +24,6 @@ import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* The ScrollView class is the main class which gets started from the command
|
||||
* line. It sets up LUA and handles the network processing.
|
||||
@ -115,29 +115,10 @@ public class ScrollView {
|
||||
first = !first;
|
||||
}
|
||||
assert first;
|
||||
} else if (SVImageHandler.getReadImageData() == false) {
|
||||
// If we are currently not transmitting an image, process this
|
||||
// normally.
|
||||
} else {
|
||||
// Process this normally.
|
||||
processInput(inputLine);
|
||||
}
|
||||
// We are still transmitting image data, but there seems to be some
|
||||
// command at the
|
||||
// end of the message attached as well. Thus, we have to split it
|
||||
// accordingly and
|
||||
// first generate the image and afterwards process the remaining
|
||||
// message.
|
||||
else if (inputLine.length() >
|
||||
SVImageHandler.getMissingRemainingBytes()) {
|
||||
String luaCmd = inputLine.substring(
|
||||
SVImageHandler.getMissingRemainingBytes());
|
||||
String imgData = inputLine.substring(0,
|
||||
SVImageHandler.getMissingRemainingBytes());
|
||||
SVImageHandler.parseData(imgData);
|
||||
processInput(luaCmd);
|
||||
} else { // We are still in the middle of image data and have not
|
||||
// reached the end yet.
|
||||
SVImageHandler.parseData(inputLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Some connection error
|
||||
@ -228,6 +209,9 @@ public class ScrollView {
|
||||
|
||||
/** Executes the LUA command parsed as parameter. */
|
||||
private static void processInput(String inputLine) {
|
||||
if (inputLine == null) {
|
||||
return;
|
||||
}
|
||||
// Execute a function encoded as a LUA statement! Yuk!
|
||||
if (inputLine.charAt(0) == 'w') {
|
||||
// This is a method call on a window. Parse it.
|
||||
@ -298,11 +282,6 @@ public class ScrollView {
|
||||
} else if (func.equals("drawText")) {
|
||||
windows.get(windowID).drawText(intList.get(0), intList.get(1),
|
||||
stringList.get(0));
|
||||
} else if (func.equals("openImage")) {
|
||||
windows.get(windowID).openImage(stringList.get(0));
|
||||
} else if (func.equals("drawImage")) {
|
||||
windows.get(windowID).drawImage(stringList.get(0),
|
||||
intList.get(0), intList.get(1));
|
||||
} else if (func.equals("addMenuBarItem")) {
|
||||
if (boolList.size() > 0) {
|
||||
windows.get(windowID).addMenuBarItem(stringList.get(0),
|
||||
@ -337,12 +316,12 @@ public class ScrollView {
|
||||
} else if (func.equals("zoomRectangle")) {
|
||||
windows.get(windowID).zoomRectangle(intList.get(0), intList.get(1),
|
||||
intList.get(2), intList.get(3));
|
||||
} else if (func.equals("createImage")) {
|
||||
windows.get(windowID).createImage(stringList.get(0), intList.get(0),
|
||||
intList.get(1), intList.get(2));
|
||||
} else if (func.equals("readImage")) {
|
||||
PImage image = SVImageHandler.readImage(intList.get(2), in);
|
||||
windows.get(windowID).drawImage(image, intList.get(0), intList.get(1));
|
||||
} else if (func.equals("drawImage")) {
|
||||
windows.get(windowID).drawImage(stringList.get(0),
|
||||
intList.get(0), intList.get(1));
|
||||
PImage image = new PImage(stringList.get(0));
|
||||
windows.get(windowID).drawImage(image, intList.get(0), intList.get(1));
|
||||
} else if (func.equals("destroy")) {
|
||||
windows.get(windowID).destroy();
|
||||
}
|
||||
|
@ -25,11 +25,11 @@ import java.awt.event.WindowListener;
|
||||
|
||||
import javax.swing.Timer;
|
||||
|
||||
import edu.umd.cs.piccolo.PCamera;
|
||||
import edu.umd.cs.piccolo.PNode;
|
||||
import edu.umd.cs.piccolo.event.PBasicInputEventHandler;
|
||||
import edu.umd.cs.piccolo.event.PInputEvent;
|
||||
import edu.umd.cs.piccolo.nodes.PPath;
|
||||
import org.piccolo2d.PCamera;
|
||||
import org.piccolo2d.PNode;
|
||||
import org.piccolo2d.event.PBasicInputEventHandler;
|
||||
import org.piccolo2d.event.PInputEvent;
|
||||
import org.piccolo2d.nodes.PPath;
|
||||
|
||||
/**
|
||||
* The ScrollViewEventHandler takes care of any events which might happen on the
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright 2007 Google Inc. All Rights Reserved.
|
||||
//
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); You may not
|
||||
// use this file except in compliance with the License. You may obtain a copy of
|
||||
// the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
|
||||
@ -10,219 +10,60 @@
|
||||
|
||||
package com.google.scrollview.ui;
|
||||
|
||||
import edu.umd.cs.piccolo.nodes.PImage;
|
||||
import org.piccolo2d.nodes.PImage;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
/**
|
||||
* The ScrollViewImageHandler is a helper class which takes care of image
|
||||
* processing. It is used to construct an Image from the message-stream and
|
||||
* basically consists of a number of utility functions to process the input
|
||||
* stream.
|
||||
*
|
||||
*
|
||||
* @author wanke@google.com
|
||||
*/
|
||||
public class SVImageHandler {
|
||||
/**
|
||||
* Stores a mapping from the name of the string to its actual image. It
|
||||
* enables us to re-use images without having to load or transmit them again
|
||||
*/
|
||||
static HashMap<String, PImage> images = new HashMap<String, PImage>();
|
||||
|
||||
/** A global flag stating whether we are currently expecting Image data */
|
||||
static boolean readImageData = false;
|
||||
|
||||
// TODO(wanke) Consider moving all this into an SVImage class.
|
||||
/** These are all values belonging to the image which is currently being read */
|
||||
static String imageName = null; // Image name
|
||||
static int bytesRead = 0; // Nr. of bytes already read
|
||||
static int bpp = 0; // Bit depth
|
||||
static int pictureArray[]; // The array holding the actual image
|
||||
|
||||
static int bytePerPixel = 0; // # of used bytes to transmit a pixel (32 bpp
|
||||
// -> 7 BPP)
|
||||
static int width = 0;
|
||||
static int height = 0;
|
||||
|
||||
/* All methods are static, so we forbid to construct SVImageHandler objects */
|
||||
private SVImageHandler() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a binary input string (consisting of '0' and '1' characters) and
|
||||
* converts it to an integer representation usable as image data.
|
||||
* Reads size bytes from the stream in and interprets it as an image file,
|
||||
* encoded as png, and then text-encoded as base 64, returning the decoded
|
||||
* bitmap.
|
||||
*
|
||||
* @param size The size of the image file.
|
||||
* @param in The input stream from which to read the bytes.
|
||||
*/
|
||||
private static int[] processBinaryImage(String inputLine) {
|
||||
int BLACK = 0;
|
||||
int WHITE = Integer.MAX_VALUE;
|
||||
|
||||
int[] imgData = new int[inputLine.length()];
|
||||
|
||||
for (int i = 0; i < inputLine.length(); i++) {
|
||||
if (inputLine.charAt(i) == '0') {
|
||||
imgData[i] = WHITE;
|
||||
} else if (inputLine.charAt(i) == '1') {
|
||||
imgData[i] = BLACK;
|
||||
} // BLACK is default anyway
|
||||
else { // Something is wrong: We did get unexpected data
|
||||
System.out.println("Error: unexpected non-image-data: ("
|
||||
+ SVImageHandler.bytesRead + "," + inputLine.length() + ","
|
||||
+ (SVImageHandler.height * SVImageHandler.width) + ")");
|
||||
System.exit(1);
|
||||
public static PImage readImage(int size, BufferedReader in) {
|
||||
char[] charbuffer = new char[size];
|
||||
int numRead = 0;
|
||||
while (numRead < size) {
|
||||
int newRead = -1;
|
||||
try {
|
||||
newRead = in.read(charbuffer, numRead, size - numRead);
|
||||
} catch (IOException e) {
|
||||
System.out.println("Failed to read image data from socket" + e.getMessage());
|
||||
}
|
||||
if (newRead < 0) {
|
||||
return null;
|
||||
}
|
||||
numRead += newRead;
|
||||
}
|
||||
return imgData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an input string with pixel depth of 8 (represented by 2 bytes in
|
||||
* hexadecimal format, e.g. FF for white) and converts it to an
|
||||
* integer representation usable as image data
|
||||
*/
|
||||
private static int[] processGrayImage(String inputLine) {
|
||||
int[] imgData = new int[inputLine.length() / 2];
|
||||
// Note: This is really inefficient, splitting it 2-byte-arrays in one pass
|
||||
// would be wa faster than substring everytime.
|
||||
for (int i = 0; i < inputLine.length(); i +=2) {
|
||||
String s = inputLine.substring(i, i+1);
|
||||
imgData[i] = Integer.parseInt(s, 16);
|
||||
// Convert the character data to binary.
|
||||
byte[] binarydata = DatatypeConverter.parseBase64Binary(new String(charbuffer));
|
||||
// Convert the binary data to a byte stream and parse to image.
|
||||
ByteArrayInputStream byteStream = new ByteArrayInputStream(binarydata);
|
||||
try {
|
||||
PImage img = new PImage(ImageIO.read(byteStream));
|
||||
return img;
|
||||
} catch (IOException e) {
|
||||
System.out.println("Failed to decode image data from socket" + e.getMessage());
|
||||
}
|
||||
|
||||
return imgData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an input string with pixel depth of 32 (represented by HTML-like
|
||||
* colors in hexadecimal format, e.g. #00FF00 for green) and converts it to an
|
||||
* integer representation usable as image data
|
||||
*/
|
||||
private static int[] process32bppImage(String inputLine) {
|
||||
|
||||
String[] strData = inputLine.split("#");
|
||||
int[] imgData = new int[strData.length - 1];
|
||||
|
||||
for (int i = 1; i < strData.length; i++) {
|
||||
imgData[i - 1] = Integer.parseInt(strData[i], 16);
|
||||
}
|
||||
|
||||
return imgData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when all image data is transmitted. Generates the actual image used
|
||||
* by java and puts it into the images-hashmap.
|
||||
*/
|
||||
private static void closeImage() {
|
||||
|
||||
BufferedImage bi = null;
|
||||
if (bpp == 1) {
|
||||
bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
|
||||
} else if (bpp == 8) {
|
||||
bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
|
||||
} else if (bpp == 32) {
|
||||
bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
} else {
|
||||
System.out.println("Unsupported Image Type: " + bpp + " bpp");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
bi.setRGB(0, 0, width, height, pictureArray, 0, width);
|
||||
|
||||
PImage img = new PImage(bi);
|
||||
|
||||
images.put(imageName, img);
|
||||
|
||||
imageName = null;
|
||||
readImageData = false;
|
||||
|
||||
System.out.println("(server, #Bytes:" + bytesRead + ") Image Completed");
|
||||
|
||||
bytesRead = 0;
|
||||
bpp = 0;
|
||||
}
|
||||
|
||||
/** Starts creation of a new image. */
|
||||
public static void createImage(String name, int width, int height,
|
||||
int bitsPerPixel) {
|
||||
// Create buffered image that does not support transparency
|
||||
bpp = bitsPerPixel;
|
||||
if (bpp == 1) {
|
||||
bytePerPixel = 1;
|
||||
} else if (bpp == 8) {
|
||||
bytePerPixel = 2;
|
||||
} else if (bpp == 32) {
|
||||
bytePerPixel = 7;
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"bpp should be 1 (binary), 8 (gray) or 32 (argb), is " + bpp);
|
||||
}
|
||||
if (imageName != null) {
|
||||
throw new IllegalArgumentException("Image " + imageName + " already opened!");
|
||||
}
|
||||
else {
|
||||
imageName = name;
|
||||
bytesRead = 0;
|
||||
readImageData = true;
|
||||
SVImageHandler.height = height;
|
||||
SVImageHandler.width = width;
|
||||
pictureArray = new int[width * height];
|
||||
}
|
||||
|
||||
System.out.println("Processing Image with " + bpp + " bpp, size " + width + "x" + height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an Image from location. This means the image does not have to be
|
||||
* actually transfered over the network. Thus, it is a lot faster than using
|
||||
* the createImage method.
|
||||
*
|
||||
* @param location The (local) location from where to open the file. This is
|
||||
* also the internal name associated with the image (if you want to draw it).
|
||||
*/
|
||||
public static void openImage(String location) {
|
||||
PImage img = new PImage(location);
|
||||
images.put(location, img);
|
||||
}
|
||||
|
||||
/** Find the image corresponding to a given name */
|
||||
public static PImage getImage(String name) {
|
||||
return images.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets called while currently reading image data. Decides, how to process it
|
||||
* (which image type, whether all data is there).
|
||||
*/
|
||||
public static void parseData(String inputLine) {
|
||||
int[] data = null;
|
||||
|
||||
if (bpp == 1) {
|
||||
data = processBinaryImage(inputLine);
|
||||
} else if (bpp == 8) {
|
||||
data = processGrayImage(inputLine);
|
||||
} else if (bpp == 32) {
|
||||
data = process32bppImage(inputLine);
|
||||
} else {
|
||||
System.out.println("Unsupported Bit Type: " + bpp);
|
||||
}
|
||||
|
||||
System.arraycopy(data, 0, pictureArray, bytesRead, data.length);
|
||||
bytesRead += data.length;
|
||||
|
||||
// We have read all image data - close the image
|
||||
if (bytesRead == (height * width)) {
|
||||
closeImage();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns whether we a currently reading image data or not */
|
||||
public static boolean getReadImageData() {
|
||||
return readImageData;
|
||||
}
|
||||
|
||||
/** Computes how many bytes of the image data are still missing */
|
||||
public static int getMissingRemainingBytes() {
|
||||
return (height * width * bytePerPixel) - bytesRead;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -14,19 +14,18 @@ import com.google.scrollview.ScrollView;
|
||||
import com.google.scrollview.events.SVEvent;
|
||||
import com.google.scrollview.events.SVEventHandler;
|
||||
import com.google.scrollview.events.SVEventType;
|
||||
import com.google.scrollview.ui.SVImageHandler;
|
||||
import com.google.scrollview.ui.SVMenuBar;
|
||||
import com.google.scrollview.ui.SVPopupMenu;
|
||||
|
||||
import edu.umd.cs.piccolo.PCamera;
|
||||
import edu.umd.cs.piccolo.PCanvas;
|
||||
import edu.umd.cs.piccolo.PLayer;
|
||||
import org.piccolo2d.PCamera;
|
||||
import org.piccolo2d.PCanvas;
|
||||
import org.piccolo2d.PLayer;
|
||||
|
||||
import edu.umd.cs.piccolo.nodes.PImage;
|
||||
import edu.umd.cs.piccolo.nodes.PPath;
|
||||
import edu.umd.cs.piccolo.nodes.PText;
|
||||
import edu.umd.cs.piccolo.util.PPaintContext;
|
||||
import edu.umd.cs.piccolox.swing.PScrollPane;
|
||||
import org.piccolo2d.nodes.PImage;
|
||||
import org.piccolo2d.nodes.PPath;
|
||||
import org.piccolo2d.nodes.PText;
|
||||
import org.piccolo2d.util.PPaintContext;
|
||||
import org.piccolo2d.extras.swing.PScrollPane;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.BorderLayout;
|
||||
@ -136,21 +135,6 @@ public class SVWindow extends JFrame {
|
||||
layer.removeAllChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start setting up a new image. The server will now expect image data until
|
||||
* the image is complete.
|
||||
*
|
||||
* @param internalName The unique name of the new image
|
||||
* @param width Image width
|
||||
* @param height Image height
|
||||
* @param bitsPerPixel The bit depth (currently supported: 1 (binary) and 32
|
||||
* (ARGB))
|
||||
*/
|
||||
public void createImage(String internalName, int width, int height,
|
||||
int bitsPerPixel) {
|
||||
SVImageHandler.createImage(internalName, width, height, bitsPerPixel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start setting up a new polyline. The server will now expect
|
||||
* polyline data until the polyline is complete.
|
||||
@ -168,8 +152,20 @@ public class SVWindow extends JFrame {
|
||||
* Draw the now complete polyline.
|
||||
*/
|
||||
public void drawPolyline() {
|
||||
PPath pn = PPath.createPolyline(ScrollView.polylineXCoords,
|
||||
ScrollView.polylineYCoords);
|
||||
int numCoords = ScrollView.polylineXCoords.length;
|
||||
if (numCoords < 2) {
|
||||
return;
|
||||
}
|
||||
PPath pn = PPath.createLine(ScrollView.polylineXCoords[0],
|
||||
ScrollView.polylineYCoords[0],
|
||||
ScrollView.polylineXCoords[1],
|
||||
ScrollView.polylineYCoords[1]);
|
||||
pn.reset();
|
||||
pn.moveTo(ScrollView.polylineXCoords[0], ScrollView.polylineYCoords[0]);
|
||||
for (int p = 1; p < numCoords; ++p) {
|
||||
pn.lineTo(ScrollView.polylineXCoords[p], ScrollView.polylineYCoords[p]);
|
||||
}
|
||||
pn.closePath();
|
||||
ScrollView.polylineSize = 0;
|
||||
pn.setStrokePaint(currentPenColor);
|
||||
pn.setPaint(null); // Don't fill the polygon - this is just a polyline.
|
||||
@ -323,8 +319,7 @@ public class SVWindow extends JFrame {
|
||||
* memory, so if you intend to redraw an image, you do not have to use
|
||||
* createImage again.
|
||||
*/
|
||||
public void drawImage(String internalName, int x_pos, int y_pos) {
|
||||
PImage img = SVImageHandler.getImage(internalName);
|
||||
public void drawImage(PImage img, int x_pos, int y_pos) {
|
||||
img.setX(x_pos);
|
||||
img.setY(y_pos);
|
||||
layer.addChild(img);
|
||||
@ -629,15 +624,4 @@ public class SVWindow extends JFrame {
|
||||
setVisible(false);
|
||||
// dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an image from a given file location and store it in memory. Pro:
|
||||
* Faster than createImage. Con: Works only on the local file system.
|
||||
*
|
||||
* @param filename The path to the image.
|
||||
*/
|
||||
public void openImage(String filename) {
|
||||
SVImageHandler.openImage(filename);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -172,6 +172,8 @@ void* ScrollView::MessageReceiver(void* a) {
|
||||
sv->Signal();
|
||||
sv->Signal();
|
||||
}
|
||||
} else {
|
||||
delete cur; // Applied to no window.
|
||||
}
|
||||
svmap_mu->Unlock();
|
||||
|
||||
@ -382,6 +384,9 @@ ScrollView::~ScrollView() {
|
||||
delete mutex_;
|
||||
delete semaphore_;
|
||||
delete points_;
|
||||
for (int i = 0; i < SVET_COUNT; i++) {
|
||||
delete event_table_[i];
|
||||
}
|
||||
#endif // GRAPHICS_DISABLED
|
||||
}
|
||||
|
||||
@ -766,77 +771,44 @@ void ScrollView::ZoomToRectangle(int x1, int y1, int x2, int y2) {
|
||||
|
||||
// Send an image of type Pix.
|
||||
void ScrollView::Image(struct Pix* image, int x_pos, int y_pos) {
|
||||
int width = image->w;
|
||||
int height = image->h;
|
||||
l_uint32 bpp = image->d;
|
||||
++image_index_;
|
||||
// PIX* do not have a unique identifier/name associated, so name them "lept".
|
||||
SendMsg("createImage('lept%d',%d,%d,%d)", image_index_, width, height, bpp);
|
||||
|
||||
if (bpp == 32) {
|
||||
Transfer32bppImage(image);
|
||||
} else if (bpp == 8) {
|
||||
TransferGrayImage(image);
|
||||
} else if (bpp == 1) {
|
||||
TransferBinaryImage(image);
|
||||
}
|
||||
// PIX* do not have a unique identifier/name associated, so name them "lept".
|
||||
SendMsg("drawImage('lept%d',%d,%d)", image_index_, x_pos, y_pos);
|
||||
}
|
||||
|
||||
// Sends each pixel as hex value like html, e.g. #00FF00 for green.
|
||||
void ScrollView::Transfer32bppImage(PIX* image) {
|
||||
int ppL = pixGetWidth(image);
|
||||
int h = pixGetHeight(image);
|
||||
int wpl = pixGetWpl(image);
|
||||
int transfer_size= ppL * 7 + 2;
|
||||
char* pixel_data = new char[transfer_size];
|
||||
for (int y = 0; y < h; ++y) {
|
||||
l_uint32* data = pixGetData(image) + y*wpl;
|
||||
for (int x = 0; x < ppL; ++x, ++data) {
|
||||
snprintf(&pixel_data[x*7], 7, "#%.2x%.2x%.2x",
|
||||
GET_DATA_BYTE(data, COLOR_RED),
|
||||
GET_DATA_BYTE(data, COLOR_GREEN),
|
||||
GET_DATA_BYTE(data, COLOR_BLUE));
|
||||
}
|
||||
pixel_data[transfer_size - 2] = '\n';
|
||||
pixel_data[transfer_size - 1] = '\0';
|
||||
SendRawMessage(pixel_data);
|
||||
}
|
||||
delete[] pixel_data;
|
||||
}
|
||||
|
||||
// Sends for each pixel either '1' or '0'.
|
||||
void ScrollView::TransferGrayImage(PIX* image) {
|
||||
char* pixel_data = new char[image->w * 2 + 2];
|
||||
for (int y = 0; y < image->h; y++) {
|
||||
l_uint32* data = pixGetData(image) + y * pixGetWpl(image);
|
||||
for (int x = 0; x < image->w; x++) {
|
||||
snprintf(&pixel_data[x*2], 2, "%.2x", (GET_DATA_BYTE(data, x)));
|
||||
pixel_data[image->w * 2] = '\n';
|
||||
pixel_data[image->w * 2 + 1] = '\0';
|
||||
SendRawMessage(pixel_data);
|
||||
l_uint8* data;
|
||||
size_t size;
|
||||
pixWriteMem(&data, &size, image, IFF_PNG);
|
||||
int base64_len = (size + 2) / 3 * 4;
|
||||
SendMsg("readImage(%d,%d,%d)", x_pos, y_pos, base64_len);
|
||||
// Base64 encode the data.
|
||||
const char kBase64Table[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '+', '/',
|
||||
};
|
||||
char* base64 = new char[base64_len + 1];
|
||||
memset(base64, '=', base64_len);
|
||||
base64[base64_len] = '\0';
|
||||
int remainder = 0;
|
||||
int bits_left = 0;
|
||||
int code_len = 0;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
int code = (data[i] >> (bits_left + 2)) | remainder;
|
||||
base64[code_len++] = kBase64Table[code & 63];
|
||||
bits_left += 2;
|
||||
remainder = data[i] << (6 - bits_left);
|
||||
if (bits_left == 6) {
|
||||
base64[code_len++] = kBase64Table[remainder & 63];
|
||||
bits_left = 0;
|
||||
remainder = 0;
|
||||
}
|
||||
}
|
||||
delete [] pixel_data;
|
||||
}
|
||||
|
||||
// Sends for each pixel either '1' or '0'.
|
||||
void ScrollView::TransferBinaryImage(PIX* image) {
|
||||
char* pixel_data = new char[image->w + 2];
|
||||
for (int y = 0; y < image->h; y++) {
|
||||
l_uint32* data = pixGetData(image) + y * pixGetWpl(image);
|
||||
for (int x = 0; x < image->w; x++) {
|
||||
if (GET_DATA_BIT(data, x))
|
||||
pixel_data[x] = '1';
|
||||
else
|
||||
pixel_data[x] = '0';
|
||||
}
|
||||
pixel_data[image->w] = '\n';
|
||||
pixel_data[image->w + 1] = '\0';
|
||||
SendRawMessage(pixel_data);
|
||||
}
|
||||
delete [] pixel_data;
|
||||
if (bits_left > 0)
|
||||
base64[code_len++] = kBase64Table[remainder & 63];
|
||||
SendRawMessage(base64);
|
||||
delete [] base64;
|
||||
free(data);
|
||||
}
|
||||
|
||||
// Escapes the ' character with a \, so it can be processed by LUA.
|
||||
|
@ -297,12 +297,12 @@ static std::string ScrollViewCommand(std::string scrollview_path) {
|
||||
// Also the path has to be separated by ; on windows and : otherwise.
|
||||
#ifdef _WIN32
|
||||
const char* cmd_template = "-Djava.library.path=%s -cp %s/ScrollView.jar;"
|
||||
"%s/piccolo-1.2.jar;%s/piccolox-1.2.jar"
|
||||
"%s/piccolo2d-core-3.0.jar:%s/piccolo2d-extras-3.0.jar"
|
||||
" com.google.scrollview.ScrollView";
|
||||
#else
|
||||
const char* cmd_template = "-c \"trap 'kill %%1' 0 1 2 ; java "
|
||||
"-Xms1024m -Xmx2048m -Djava.library.path=%s -cp %s/ScrollView.jar:"
|
||||
"%s/piccolo-1.2.jar:%s/piccolox-1.2.jar"
|
||||
"%s/piccolo2d-core-3.0.jar:%s/piccolo2d-extras-3.0.jar"
|
||||
" com.google.scrollview.ScrollView"
|
||||
" & wait\"";
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user