I am using the below code to read through the Windows Application Event Log using JNA. I want to be able to specify which event to start at instead of always starting with the first event. Does anyone have any suggestions?
import java.io.IOException;
import com.sun.jna.*;
import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.WinNT.*;
import com.sun.jna.ptr.IntByReference;
public class test {
public static void main(String[] args) throws NumberFormatException, IOException {
HANDLE h = Advapi32.INSTANCE.OpenEventLog("ServerName", "Application");
IntByReference pnBytesRead = new IntByReference();
IntByReference pnMinNumberOfBytesNeeded = new IntByReference();
Memory buffer = new Memory(1024 * 64);
IntByReference pOldestRecord = new IntByReference();
assertTrue(Advapi32.INSTANCE.GetOldestEventLogRecord(h, pOldestRecord));
int dwRecord = pOldestRecord.getValue();
int rc = 0;
while(true) {
if (! Advapi32.INSTANCE.ReadEventLog(h, WinNT.EVENTLOG_SEQUENTIAL_READ | WinNT.EVENTLOG_FORWARDS_READ,
0, buffer, (int) buffer.size(), pnBytesRead, pnMinNumberOfBytesNeeded)) {
rc = Kernel32.INSTANCE.GetLastError();
if (rc == W32Errors.ERROR_INSUFFICIENT_BUFFER) {
buffer = new Memory(pnMinNumberOfBytesNeeded.getValue());
continue;
}
break;
}
int dwRead = pnBytesRead.getValue();
Pointer pevlr = buffer;
while (dwRead > 0)
{
EVENTLOGRECORD record = new EVENTLOGRECORD(pevlr);
System.out.println(dwRecord + " Event ID: " + record.EventID.intValue());
dwRecord++;
dwRead -= record.Length.intValue();
pevlr = pevlr.share(record.Length.intValue());
}
}
assertTrue(rc == W32Errors.ERROR_HANDLE_EOF);
assertTrue(Advapi32.INSTANCE.CloseEventLog(h));
}
private static void assertTrue(boolean getOldestEventLogRecord) {
}
}
Bondo, here is a possible solution. In my test, it reads all 570 event logs under Application event; each event log will display in detail its event log record data.
Code solution:
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.Arrays;
import com.sun.jna.*;
import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.WinNT.*;
import com.sun.jna.ptr.IntByReference;
public class Test {
public static void main(String[] args) throws NumberFormatException, IOException {
HANDLE h = com.sun.jna.platform.win32.Advapi32.INSTANCE.OpenEventLog(null, "Application");
IntByReference pnBytesRead = new IntByReference();
IntByReference pnMinNumberOfBytesNeeded = new IntByReference();
IntByReference pOldestRecord = new IntByReference();
assertTrue(com.sun.jna.platform.win32.Advapi32.INSTANCE.GetOldestEventLogRecord(h, pOldestRecord));
int dwRecord = pOldestRecord.getValue();
System.out.println("OLD: " + dwRecord);
IntByReference pRecordCount = new IntByReference();
assertTrue(com.sun.jna.platform.win32.Advapi32.INSTANCE.GetNumberOfEventLogRecords(h, pRecordCount));
int dwRecordCnt = pRecordCount.getValue();
System.out.println("CNT: " + dwRecordCnt);
int bufSize = 0x7ffff; //(r.size()) * 2048;
Memory buffer = new Memory(bufSize);
int rc = 0;
int cnt = 0;
while(com.sun.jna.platform.win32.Advapi32.INSTANCE.ReadEventLog(h,
WinNT.EVENTLOG_SEEK_READ /*
| WinNT.EVENTLOG_SEQUENTIAL_READ */
| WinNT.EVENTLOG_FORWARDS_READ /*
| WinNT.EVENTLOG_BACKWARDS_READ*/
,
dwRecord, buffer,
bufSize,
pnBytesRead,
pnMinNumberOfBytesNeeded)) {
rc = Kernel32.INSTANCE.GetLastError();
if (rc == W32Errors.ERROR_INSUFFICIENT_BUFFER) {
break;
}
int dwRead = pnBytesRead.getValue();
Pointer pevlr = buffer;
while (dwRead > 0)
{
cnt++;
EVENTLOGRECORD record = new EVENTLOGRECORD(pevlr);
System.out.println("------------------------------------------------------------");
System.out.println(cnt+". " + dwRecord + " Event ID: " + record.EventID.shortValue() + " SID: " + record.UserSidLength);
dwRecord++;
// WCHAR SourceName[]
// WCHAR Computername[]
{
ByteBuffer names = pevlr.getByteBuffer(record.size(),
(record.UserSidLength.intValue() != 0 ? record.UserSidOffset.intValue() : record.StringOffset.intValue()) - record.size());
names.position(0);
CharBuffer namesBuf = names.asCharBuffer();
String[] splits = namesBuf.toString().split("\0");
System.out.println("SOURCE NAME: \n" + splits[0]);
System.out.println("COMPUTER NAME: \n" + splits[1]);
}
// SID UserSid
if (record.UserSidLength.intValue() != 0){
ByteBuffer sid = pevlr.getByteBuffer(record.UserSidOffset.intValue(), record.UserSidLength.intValue());
sid.position(0);
//CharBuffer sidBuf = sid.asCharBuffer();
byte[] dst = new byte[record.UserSidLength.intValue()];
sid.get(dst);
System.out.println("SID: \n" + Arrays.toString(dst));
}
else {
System.out.println("SID: \nN/A");
}
// WCHAR Strings[]
{
ByteBuffer strings = pevlr.getByteBuffer(record.StringOffset.intValue(), record.DataOffset.intValue() - record.StringOffset.intValue());
strings.position(0);
CharBuffer stringsBuf = strings.asCharBuffer();
System.out.println("STRINGS["+record.NumStrings.intValue()+"]: \n" + stringsBuf.toString());
}
// BYTE Data[]
{
ByteBuffer data = pevlr.getByteBuffer(record.DataOffset.intValue(), record.DataLength.intValue());
data.position(0);
CharBuffer dataBuf = data.asCharBuffer();
System.out.println("DATA: \n" + dataBuf.toString());
}
// CHAR Pad[]
// DWORD Length;
dwRead -= record.Length.intValue();
pevlr = pevlr.share(record.Length.intValue());
}
}
assertTrue(rc == W32Errors.ERROR_HANDLE_EOF);
assertTrue(com.sun.jna.platform.win32.Advapi32.INSTANCE.CloseEventLog(h));
}
private static void assertTrue(boolean getOldestEventLogRecord) {
}
}
Sample output (the last of the event logs):
------------------------------------------------------------
570. 26957 Event ID: 107 SID: 0
SOURCE NAME:
Report Server Windows Service (VOSTRO)
COMPUTER NAME:
CVS
SID:
N/A
STRINGS[1]:
Report Server Windows Service (VOSTRO)
DATA:
Notes:
I've set the lpBuffer at its maximum size of 0x7FFFF bytes.
It uses WinNT.EVENTLOG_SEEK_READ mode with the record number offset dwRecordOffset starts at the oldest record number.
The while loop will break when ReadEventLog() method returns zero and its GetLastError() returns W32Errors.ERROR_INSUFFICIENT_BUFFER.
The event id should be read in short for the correct value: record.EventID.shortValue()
Related
I need to set loader in assetmanager for Animation.class, i used Gifloader,that loads completly animation from GifDecoder(that creates animation from gif)
but get error:
https://i.stack.imgur.com/HkrWe.png
, error on build: https://i.stack.imgur.com/2Mpaz.png
setloader line:
manager.setLoader(Animation.class, new Gifloader(new InternalFileHandleResolver()))
Gifloader class:
package com.mygdx.testgame;
import com.badlogic.gdx.assets.AssetDescriptor;
import com.badlogic.gdx.assets.AssetLoaderParameters;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.assets.loaders.AsynchronousAssetLoader;
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
public class Gifloader extends AsynchronousAssetLoader<Animation<TextureRegion>, Gifloader.GifloaderParameter> {
private com.badlogic.gdx.graphics.g2d.Animation<TextureRegion> animresult;
public Gifloader(FileHandleResolver resolver) {
super(resolver);
}
#Override
public void loadAsync(AssetManager manager, String fileName, FileHandle file, GifloaderParameter parameter) {
animresult = (com.holidaystudios.tools.GifDecoder.loadGIFAnimation(Animation.PlayMode.LOOP,file.read()));
}
#Override
public Animation loadSync(AssetManager manager, String fileName, FileHandle file, GifloaderParameter parameter) {
return animresult;
}
#Override
public Array<AssetDescriptor> getDependencies(String fileName, FileHandle file, GifloaderParameter parameter) {
return null;
}
static public class GifloaderParameter extends AssetLoaderParameters<Animation<TextureRegion>> {
}
}
GifDecoder class:
/* Copyright by Johannes Borchardt */
/* LibGdx conversion 2014 by Anton Persson */
/* Released under Apache 2.0 */
/* https://code.google.com/p/animated-gifs-in-android/ */
package com.holidaystudios.tools;
import java.io.InputStream;
import java.util.Vector;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Animation.PlayMode;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.utils.Array;
public class GifDecoder {
/**
* File read status: No errors.
*/
public static final int STATUS_OK = 0;
/**
* File read status: Error decoding file (may be partially decoded)
*/
public static final int STATUS_FORMAT_ERROR = 1;
/**
* File read status: Unable to open source.
*/
public static final int STATUS_OPEN_ERROR = 2;
/** max decoder pixel stack size */
protected static final int MAX_STACK_SIZE = 4096;
protected InputStream in;
protected int status;
protected int width; // full image width
protected int height; // full image height
protected boolean gctFlag; // global color table used
protected int gctSize; // size of global color table
protected int loopCount = 1; // iterations; 0 = repeat forever
protected int[] gct; // global color table
protected int[] lct; // local color table
protected int[] act; // active color table
protected int bgIndex; // background color index
protected int bgColor; // background color
protected int lastBgColor; // previous bg color
protected int pixelAspect; // pixel aspect ratio
protected boolean lctFlag; // local color table flag
protected boolean interlace; // interlace flag
protected int lctSize; // local color table size
protected int ix, iy, iw, ih; // current image rectangle
protected int lrx, lry, lrw, lrh;
protected DixieMap image; // current frame
protected DixieMap lastPixmap; // previous frame
protected byte[] block = new byte[256]; // current data block
protected int blockSize = 0; // block size last graphic control extension info
protected int dispose = 0; // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
protected int lastDispose = 0;
protected boolean transparency = false; // use transparent color
protected int delay = 0; // delay in milliseconds
protected int transIndex; // transparent color index
// LZW decoder working arrays
protected short[] prefix;
protected byte[] suffix;
protected byte[] pixelStack;
protected byte[] pixels;
protected Vector<GifFrame> frames; // frames read from current file
protected int frameCount;
private static class DixieMap extends Pixmap {
DixieMap(int w, int h, Pixmap.Format f) {
super(w, h, f);
}
DixieMap(int[] data, int w, int h, Pixmap.Format f) {
super(w, h, f);
int x, y;
for(y = 0; y < h; y++) {
for(x = 0; x < w; x++) {
int pxl_ARGB8888 = data[x + y * w];
int pxl_RGBA8888 =
((pxl_ARGB8888 >> 24) & 0x000000ff) | ((pxl_ARGB8888 << 8) & 0xffffff00);
// convert ARGB8888 > RGBA8888
drawPixel(x, y, pxl_RGBA8888);
}
}
}
void getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) {
java.nio.ByteBuffer bb = getPixels();
int k, l;
for(k = y; k < y + height; k++) {
int _offset = offset;
for(l = x; l < x + width; l++) {
int pxl = bb.getInt(4 * (l + k * width));
// convert RGBA8888 > ARGB8888
pixels[_offset++] = ((pxl >> 8) & 0x00ffffff) | ((pxl << 24) & 0xff000000);
}
offset += stride;
}
}
}
private static class GifFrame {
public GifFrame(DixieMap im, int del) {
image = im;
delay = del;
}
public DixieMap image;
public int delay;
}
/**
* Gets display duration for specified frame.
*
* #param n
* int index of frame
* #return delay in milliseconds
*/
public int getDelay(int n) {
delay = -1;
if ((n >= 0) && (n < frameCount)) {
delay = frames.elementAt(n).delay;
}
return delay;
}
/**
* Gets the number of frames read from file.
*
* #return frame count
*/
public int getFrameCount() {
return frameCount;
}
/**
* Gets the first (or only) image read.
*
* #return BufferedPixmap containing first frame, or null if none.
*/
public Pixmap getPixmap() {
return getFrame(0);
}
/**
* Gets the "Netscape" iteration count, if any. A count of 0 means repeat indefinitely.
*
* #return iteration count if one was specified, else 1.
*/
public int getLoopCount() {
return loopCount;
}
/**
* Creates new frame image from current data (and previous frames as specified by their disposition codes).
*/
protected void setPixels() {
// expose destination image's pixels as int array
int[] dest = new int[width * height];
// fill in starting image contents based on last image's dispose code
if (lastDispose > 0) {
if (lastDispose == 3) {
// use image before last
int n = frameCount - 2;
if (n > 0) {
lastPixmap = getFrame(n - 1);
} else {
lastPixmap = null;
}
}
if (lastPixmap != null) {
lastPixmap.getPixels(dest, 0, width, 0, 0, width, height);
// copy pixels
if (lastDispose == 2) {
// fill last image rect area with background color
int c = 0;
if (!transparency) {
c = lastBgColor;
}
for (int i = 0; i < lrh; i++) {
int n1 = (lry + i) * width + lrx;
int n2 = n1 + lrw;
for (int k = n1; k < n2; k++) {
dest[k] = c;
}
}
}
}
}
// copy each source line to the appropriate place in the destination
int pass = 1;
int inc = 8;
int iline = 0;
for (int i = 0; i < ih; i++) {
int line = i;
if (interlace) {
if (iline >= ih) {
pass++;
switch (pass) {
case 2:
iline = 4;
break;
case 3:
iline = 2;
inc = 4;
break;
case 4:
iline = 1;
inc = 2;
break;
default:
break;
}
}
line = iline;
iline += inc;
}
line += iy;
if (line < height) {
int k = line * width;
int dx = k + ix; // start of line in dest
int dlim = dx + iw; // end of dest line
if ((k + width) < dlim) {
dlim = k + width; // past dest edge
}
int sx = i * iw; // start of line in source
while (dx < dlim) {
// map color and insert in destination
int index = ((int) pixels[sx++]) & 0xff;
int c = act[index];
if (c != 0) {
dest[dx] = c;
}
dx++;
}
}
}
image = new DixieMap(dest, width, height, Pixmap.Format.RGBA8888);
//Pixmap.createPixmap(dest, width, height, Config.ARGB_4444);
}
/**
* Gets the image contents of frame n.
*
* #return BufferedPixmap representation of frame, or null if n is invalid.
*/
public DixieMap getFrame(int n) {
if (frameCount <= 0)
return null;
n = n % frameCount;
return ((GifFrame) frames.elementAt(n)).image;
}
/**
* Reads GIF image from stream
*
* #param is
* containing GIF file.
* #return read status code (0 = no errors)
*/
public int read(InputStream is) {
init();
if (is != null) {
in = is;
readHeader();
if (!err()) {
readContents();
if (frameCount < 0) {
status = STATUS_FORMAT_ERROR;
}
}
} else {
status = STATUS_OPEN_ERROR;
}
try {
is.close();
} catch (Exception e) {
}
return status;
}
/**
* Decodes LZW image data into pixel array. Adapted from John Cristy's BitmapMagick.
*/
protected void decodeBitmapData() {
int nullCode = -1;
int npix = iw * ih;
int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi, pi;
if ((pixels == null) || (pixels.length < npix)) {
pixels = new byte[npix]; // allocate new pixel array
}
if (prefix == null) {
prefix = new short[MAX_STACK_SIZE];
}
if (suffix == null) {
suffix = new byte[MAX_STACK_SIZE];
}
if (pixelStack == null) {
pixelStack = new byte[MAX_STACK_SIZE + 1];
}
// Initialize GIF data stream decoder.
data_size = read();
clear = 1 << data_size;
end_of_information = clear + 1;
available = clear + 2;
old_code = nullCode;
code_size = data_size + 1;
code_mask = (1 << code_size) - 1;
for (code = 0; code < clear; code++) {
prefix[code] = 0; // XXX ArrayIndexOutOfBoundsException
suffix[code] = (byte) code;
}
// Decode GIF pixel stream.
datum = bits = count = first = top = pi = bi = 0;
for (i = 0; i < npix;) {
if (top == 0) {
if (bits < code_size) {
// Load bytes until there are enough bits for a code.
if (count == 0) {
// Read a new data block.
count = readBlock();
if (count <= 0) {
break;
}
bi = 0;
}
datum += (((int) block[bi]) & 0xff) << bits;
bits += 8;
bi++;
count--;
continue;
}
// Get the next code.
code = datum & code_mask;
datum >>= code_size;
bits -= code_size;
// Interpret the code
if ((code > available) || (code == end_of_information)) {
break;
}
if (code == clear) {
// Reset decoder.
code_size = data_size + 1;
code_mask = (1 << code_size) - 1;
available = clear + 2;
old_code = nullCode;
continue;
}
if (old_code == nullCode) {
pixelStack[top++] = suffix[code];
old_code = code;
first = code;
continue;
}
in_code = code;
if (code == available) {
pixelStack[top++] = (byte) first;
code = old_code;
}
while (code > clear) {
pixelStack[top++] = suffix[code];
code = prefix[code];
}
first = ((int) suffix[code]) & 0xff;
// Add a new string to the string table,
if (available >= MAX_STACK_SIZE) {
break;
}
pixelStack[top++] = (byte) first;
prefix[available] = (short) old_code;
suffix[available] = (byte) first;
available++;
if (((available & code_mask) == 0) && (available < MAX_STACK_SIZE)) {
code_size++;
code_mask += available;
}
old_code = in_code;
}
// Pop a pixel off the pixel stack.
top--;
pixels[pi++] = pixelStack[top];
i++;
}
for (i = pi; i < npix; i++) {
pixels[i] = 0; // clear missing pixels
}
}
/**
* Returns true if an error was encountered during reading/decoding
*/
protected boolean err() {
return status != STATUS_OK;
}
/**
* Initializes or re-initializes reader
*/
protected void init() {
status = STATUS_OK;
frameCount = 0;
frames = new Vector<GifFrame>();
gct = null;
lct = null;
}
/**
* Reads a single byte from the input stream.
*/
protected int read() {
int curByte = 0;
try {
curByte = in.read();
} catch (Exception e) {
status = STATUS_FORMAT_ERROR;
}
return curByte;
}
/**
* Reads next variable length block from input.
*
* #return number of bytes stored in "buffer"
*/
protected int readBlock() {
blockSize = read();
int n = 0;
if (blockSize > 0) {
try {
int count = 0;
while (n < blockSize) {
count = in.read(block, n, blockSize - n);
if (count == -1) {
break;
}
n += count;
}
} catch (Exception e) {
e.printStackTrace();
}
if (n < blockSize) {
status = STATUS_FORMAT_ERROR;
}
}
return n;
}
/**
* Reads color table as 256 RGB integer values
*
* #param ncolors
* int number of colors to read
* #return int array containing 256 colors (packed ARGB with full alpha)
*/
protected int[] readColorTable(int ncolors) {
int nbytes = 3 * ncolors;
int[] tab = null;
byte[] c = new byte[nbytes];
int n = 0;
try {
n = in.read(c);
} catch (Exception e) {
e.printStackTrace();
}
if (n < nbytes) {
status = STATUS_FORMAT_ERROR;
} else {
tab = new int[256]; // max size to avoid bounds checks
int i = 0;
int j = 0;
while (i < ncolors) {
int r = ((int) c[j++]) & 0xff;
int g = ((int) c[j++]) & 0xff;
int b = ((int) c[j++]) & 0xff;
tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
}
}
return tab;
}
/**
* Main file parser. Reads GIF content blocks.
*/
protected void readContents() {
// read GIF file content blocks
boolean done = false;
while (!(done || err())) {
int code = read();
switch (code) {
case 0x2C: // image separator
readBitmap();
break;
case 0x21: // extension
code = read();
switch (code) {
case 0xf9: // graphics control extension
readGraphicControlExt();
break;
case 0xff: // application extension
readBlock();
String app = "";
for (int i = 0; i < 11; i++) {
app += (char) block[i];
}
if (app.equals("NETSCAPE2.0")) {
readNetscapeExt();
} else {
skip(); // don't care
}
break;
case 0xfe:// comment extension
skip();
break;
case 0x01:// plain text extension
skip();
break;
default: // uninteresting extension
skip();
}
break;
case 0x3b: // terminator
done = true;
break;
case 0x00: // bad byte, but keep going and see what happens break;
default:
status = STATUS_FORMAT_ERROR;
}
}
}
/**
* Reads Graphics Control Extension values
*/
protected void readGraphicControlExt() {
read(); // block size
int packed = read(); // packed fields
dispose = (packed & 0x1c) >> 2; // disposal method
if (dispose == 0) {
dispose = 1; // elect to keep old image if discretionary
}
transparency = (packed & 1) != 0;
delay = readShort() * 10; // delay in milliseconds
transIndex = read(); // transparent color index
read(); // block terminator
}
/**
* Reads GIF file header information.
*/
protected void readHeader() {
String id = "";
for (int i = 0; i < 6; i++) {
id += (char) read();
}
if (!id.startsWith("GIF")) {
status = STATUS_FORMAT_ERROR;
return;
}
readLSD();
if (gctFlag && !err()) {
gct = readColorTable(gctSize);
bgColor = gct[bgIndex];
}
}
/**
* Reads next frame image
*/
protected void readBitmap() {
ix = readShort(); // (sub)image position & size
iy = readShort();
iw = readShort();
ih = readShort();
int packed = read();
lctFlag = (packed & 0x80) != 0; // 1 - local color table flag interlace
lctSize = (int) Math.pow(2, (packed & 0x07) + 1);
// 3 - sort flag
// 4-5 - reserved lctSize = 2 << (packed & 7); // 6-8 - local color
// table size
interlace = (packed & 0x40) != 0;
if (lctFlag) {
lct = readColorTable(lctSize); // read table
act = lct; // make local table active
} else {
act = gct; // make global table active
if (bgIndex == transIndex) {
bgColor = 0;
}
}
int save = 0;
if (transparency) {
save = act[transIndex];
act[transIndex] = 0; // set transparent color if specified
}
if (act == null) {
status = STATUS_FORMAT_ERROR; // no color table defined
}
if (err()) {
return;
}
decodeBitmapData(); // decode pixel data
skip();
if (err()) {
return;
}
frameCount++;
// create new image to receive frame data
image = new DixieMap(width, height, Pixmap.Format.RGBA8888);
setPixels(); // transfer pixel data to image
frames.addElement(new GifFrame(image, delay)); // add image to frame
// list
if (transparency) {
act[transIndex] = save;
}
resetFrame();
}
/**
* Reads Logical Screen Descriptor
*/
protected void readLSD() {
// logical screen size
width = readShort();
height = readShort();
// packed fields
int packed = read();
gctFlag = (packed & 0x80) != 0; // 1 : global color table flag
// 2-4 : color resolution
// 5 : gct sort flag
gctSize = 2 << (packed & 7); // 6-8 : gct size
bgIndex = read(); // background color index
pixelAspect = read(); // pixel aspect ratio
}
/**
* Reads Netscape extenstion to obtain iteration count
*/
protected void readNetscapeExt() {
do {
readBlock();
if (block[0] == 1) {
// loop count sub-block
int b1 = ((int) block[1]) & 0xff;
int b2 = ((int) block[2]) & 0xff;
loopCount = (b2 << 8) | b1;
}
} while ((blockSize > 0) && !err());
}
/**
* Reads next 16-bit value, LSB first
*/
protected int readShort() {
// read 16-bit value, LSB first
return read() | (read() << 8);
}
/**
* Resets frame state for reading next image.
*/
protected void resetFrame() {
lastDispose = dispose;
lrx = ix;
lry = iy;
lrw = iw;
lrh = ih;
lastPixmap = image;
lastBgColor = bgColor;
dispose = 0;
transparency = false;
delay = 0;
lct = null;
}
/**
* Skips variable length blocks up to and including next zero length block.
*/
protected void skip() {
do {
readBlock();
} while ((blockSize > 0) && !err());
}
public Animation<TextureRegion> getAnimation(PlayMode playMode) {
int nrFrames = getFrameCount();
Pixmap frame = getFrame(0);
int width = frame.getWidth();
int height = frame.getHeight();
int vzones = (int)Math.sqrt((double)nrFrames);
int hzones = vzones;
while(vzones * hzones < nrFrames) vzones++;
int v, h;
Pixmap target = new Pixmap(width * hzones, height * vzones, Pixmap.Format.RGBA8888);
for(h = 0; h < hzones; h++) {
for(v = 0; v < vzones; v++) {
int frameID = v + h * vzones;
if(frameID < nrFrames) {
frame = getFrame(frameID);
target.drawPixmap(frame, h * width, v * height);
}
}
}
Texture texture = new Texture(target);
Array<TextureRegion> texReg = new Array<TextureRegion>();
for(h = 0; h < hzones; h++) {
for(v = 0; v < vzones; v++) {
int frameID = v + h * vzones;
if(frameID < nrFrames) {
TextureRegion tr = new TextureRegion(texture, h * width, v * height, width, height);
texReg.add(tr);
}
}
}
float frameDuration = (float)getDelay(0);
frameDuration /= 1000; // convert milliseconds into seconds
Animation<TextureRegion> result = new Animation<TextureRegion>(frameDuration, texReg, playMode);
return result;
}
public static Animation<TextureRegion> loadGIFAnimation(Animation.PlayMode playMode, InputStream is) {
GifDecoder gdec = new GifDecoder();
gdec.read(is);
return gdec.getAnimation(playMode);
}
}
please anyone help me
I could only make this work in the syncloader and not in the asyncloader is problably because it takes too much resources.
Too avoid the errors i made a GIF class to wrap the Animation this is also to dispose the texture when its no longer needed if this is not done it will create a memory leak.
public class GIF implements Disposable {
public Animation<TextureRegion> animation;
public Texture texture;
public GIF( Animation<TextureRegion> animation ) {
Object[] object = animation.getKeyFrames();
this.animation = animation;
this.texture = ((TextureRegion) object[ 0 ]).getTexture();
}
#Override
public void dispose() {
texture.dispose();
}
}
Here is the asset loader code:
public class Gifloader extends AsynchronousAssetLoader<GIF, Gifloader.GifloaderParameter> {
private Animation<TextureRegion> animation;
public Gifloader(FileHandleResolver resolver) {
super(resolver);
this.animation = null;
}
#Override
public void loadAsync(AssetManager manager, String fileName, FileHandle file, GifloaderParameter parameter) {
}
#Override
public GIF loadSync(AssetManager manager, String fileName, FileHandle file, GifloaderParameter parameter) {
PlayMode playMode = PlayMode.LOOP;
if ( parameter != null ){
playMode = parameter.playMode;
}
animation = (GifDecoder.loadGIFAnimation( playMode, file.read() ));
return new GIF( animation );
}
#SuppressWarnings( "rawtypes" )
#Override
public Array<AssetDescriptor> getDependencies(String fileName, FileHandle file, GifloaderParameter parameter) {
return null;
}
public static class GifloaderParameter extends AssetLoaderParameters<GIF> {
public PlayMode playMode = PlayMode.LOOP;
}
}
I'm working on this code to manage and save data coming from the Microsoft kinect, the data are stored in the int array int[] depthValues, what I'd like to do is to store and save an average of more frames (let's say 10), in order to get smoother data, leaving the remaining part of the code as it is.
Here's the code:
import java.io.File;
import SimpleOpenNI.*;
import java.util.*;
SimpleOpenNI kinect;
void setup()
{
size(640, 480);
kinect = new SimpleOpenNI(this);
kinect.enableDepth();
}
int precedente = millis();
void draw()
{
kinect.update();
PImage depthImage = kinect.depthImage();
image(depthImage, 0, 0);
int[] depthValues = kinect.depthMap();
StringBuilder sb = new StringBuilder();
Deque<Integer> row = new LinkedList<Integer>();
int kinectheight = 770; // kinect distance from the baselevel [mm]
int scaleFactor = 1;
int pixelsPerRow = 640;
int pixelsToSkip = 40;
int rowNum = 0;
for (int i = 0; i < depthValues.length; i++) {
if (i > 0 && i == (rowNum + 1) * pixelsPerRow) {
fillStringBuilder(sb, row);
rowNum++;
sb.append("\n");
row = new LinkedList<Integer>();
}
if (i >= (rowNum * pixelsPerRow) + pixelsToSkip) {
row.addFirst((kinectheight - depthValues[i]) * scaleFactor);
}
}
fillStringBuilder(sb, row);
String kinectDEM = sb.toString();
final String[] txt= new String[1]; //creates a string array of 2 elements
int savingtimestep = 15000; // time step in millisec between each saving
if (millis() > precedente + savingtimestep) {
txt[0] = "ncols 600\nnrows 480\nxllcorner 0\nyllcorner 0\ncellsize 91.6667\nNODATA_value 10\n" +kinectDEM;
saveStrings("kinectDEM0.tmp", txt);
precedente = millis();
// delete the old .txt file, from kinectDEM1 to kinectDEMtrash
File f = new File (sketchPath("kinectDEM1.txt"));
boolean success = f.delete();
// rename the old .txt file, from kinectDEM0 to kinectDEM1
File oldName1 = new File(sketchPath("kinectDEM0.txt"));
File newName1 = new File(sketchPath("kinectDEM1.txt"));
oldName1.renameTo(newName1);
// rename kinectDEM0.tmp file to kinectDEM0.txt
File oldName2 = new File(sketchPath("kinectDEM0.tmp"));
File newName2 = new File(sketchPath("kinectDEM0.txt"));
oldName2.renameTo(newName2);
}
}
void fillStringBuilder(StringBuilder sb, Deque<Integer> row) {
boolean emptyRow = false;
while (!emptyRow) {
Integer val = row.pollFirst();
if (val == null) {
emptyRow = true;
} else {
sb.append(val);
val = row.peekFirst();
if (val != null) {
sb.append(" ");
}
}
}
}
You have an int[] array variable named depthValues. You can use this value just like you can use any other value. In other words, you can create an array or ArrayList that holds multiple int[] values.
Here's how you might use an ArrayList to hold previous values:
ArrayList<int[]> previousDepthValues = new ArrayList<int[]>();
void draw(){
//add current depth map to ArrayList
previousDepthValues.add(kinect.depthMap());
//limit the ArrayList to hold 10 values
if(previousDepthValues.size() == 11){
previousDepthValues.remove(0);
}
//create an array to hold the averaged values
int[] averageDepthValues = new int[previousDepthValues.get(0).length];
//loop over the 10 previous depth values in the ArrayList
for(int[] depthValue : previousDepthValues){
//loop over the ints in each previous depth values array
for(int i = 0; i < averageDepthValues.length; i++){
//add all of the values up
averageDepthValues[i] += depthValue[i];
}
}
//divide each number to get the average
for(int i = 0; i < averageDepthValues.length; i++){
averageDepthValues[i] /= averageDepthValues.length;
}
//averageDepthValues now holds the average of the last 10 frames
}
So I keep getting illegal start of expression errors around line 30 when trying to run my DiceGame program which is practice with methods. Here's my code:
import java.util.Scanner;
public class DiceGame
{
public static void main(String[] args)
{
final int RANGE = 6;
Scanner input = new Scanner(System.in);
int userGuess = input.next();
int throwResult = throw2Dice(RANGE);
int programGuess = throw2Dice(RANGE);
int userError = Math.abs(throwResult - userGuess);
int programError = Math.abs(throwResult - programGuess);
boolean userWins = false;
if(userError < programError)
{
userWins = true;
{
System.out.println("Your guess was: " + userGuess + " the program's guess was: " + programGuess + " and the result was: " + throwResult);
if(userWins == false)
System.out.println("Program Wins!!!");
else
System.out.println("User Wins!!!");
}
public static int throw2Dice(int r)
{
int number1 = (Math.random() * r + 1);
int number2 = (Math.random() * r + 1);
int sum = number1 + number2;
return sum;
}
}
if(userError < programError)
{
userWins = true;
{
You have two open braces instead of an open brace and a close brace.
I want to display a listfield with live image in all rows of the listfield
check out this
also use the following code for displaying live images:
public static String getImageFromUrl(String url) {
//Image img = null;
String imageData = null;
try
{
imageData = getDataFromUrl(url);
//img = Image.createImage(imageData.getBytes(), 0,imageData.length() );
}
catch(Exception e1) {
e1.printStackTrace();
}
return imageData;
}
public static String getDataFromUrl(String url)
throws IOException {
StringBuffer b = new StringBuffer();
InputStream is = null;
HttpConnection c = null;
long len = 0 ;
int ch = 0;
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(url);
if (connDesc != null)
{
//HttpConnection httpConn;
c = (HttpConnection)connDesc.getConnection();
}
// c = (HttpConnection)Connector.open(url);
is = c.openInputStream();
len = c.getLength();
if( len != -1) {
// Read exactly Content-Length bytes
for(int i =0 ; i < len ; i++ )
if((ch = is.read()) != -1) {
b.append((char) ch);
}
} else {
//Read until the connection is closed.
while ((ch = is.read()) != -1) {
len = is.available() ;
b.append((char)ch);
}
}
is.close();
c.close();
return b.toString();
}
Hope this will help you.
I'm having an interesting anomaly when displaying a listfield on the blackberry simulator:
The top item is the height of a single line of text (about 12 pixels) while the rest are fine.
Does anyone know why only the top item is being drawn this way? Also, when I add an empty venue in position 0, it still displays the first actual venue this way (item in position 1).
Not sure what to do.
Thanks for any help.
The layout looks like this:
-----------------------------------
| *part of image* | title |
-----------------------------------
| | title |
| * full image * | address |
| | city, zip |
-----------------------------------
The object is called like so:
listField = new ListField( venueList.size() );
listField.setCallback( this );
listField.setSelectedIndex(-1);
_middle.add( listField );
Here is the drawListRow code:
public void drawListRow( ListField listField, Graphics graphics,
int index, int y, int width )
{
listField.setRowHeight(90);
Hashtable item = (Hashtable) venueList.elementAt( index );
String venue_name = (String) item.get("name");
String image_url = (String) item.get("image_url");
String address = (String) item.get("address");
String city = (String) item.get("city");
String zip = (String) item.get("zip");
EncodedImage img = null;
try
{
String filename = image_url.substring(image_url.indexOf("crop/")
+ 5, image_url.length() );
FileConnection fconn = (FileConnection)Connector.open(
"file:///SDCard/Blackberry/project1/" + filename,
Connector.READ);
if ( !fconn.exists() )
{
}
else
{
InputStream input = fconn.openInputStream();
byte[] data = new byte[(int)fconn.fileSize()];
input.read(data);
input.close();
if(data.length > 0)
{
EncodedImage rawimg = EncodedImage.createEncodedImage(
data, 0, data.length);
int dw = Fixed32.toFP(Display.getWidth());
int iw = Fixed32.toFP(rawimg.getWidth());
int sf = Fixed32.div(iw, dw);
img = rawimg.scaleImage32(sf * 4, sf * 4);
}
else
{
}
}
}
catch(IOException ef)
{
}
graphics.drawText( venue_name, 140, y, 0, width );
graphics.drawText( address, 140, y + 15, 0, width );
graphics.drawText( city + ", " + zip, 140, y + 30, 0, width );
if(img != null)
{
graphics.drawImage(0, y, img.getWidth(), img.getHeight(),
img, 0, 0, 0);
}
}
setRowHeight should be called once after construction of ListField, not inside of drawListRow on each time row is repainted:
listField = new ListField( venueList.size() );
listField.setRowHeight(90);
listField.setCallback( this );
listField.setSelectedIndex(-1);
_middle.add( listField );
Aman,
Hopefully you can use this for something. You should be able to extract the list field data from this wildly out of control class. Remember, this is a work in progress, so you will have to strip out the things that are quite clearly custom to my app. Like the image handling that relies on a substring for a file name.
It works fine for me, but it will totally not work for anyone htat just copies and pastes, so good luck...
package venue;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import net.rim.device.api.math.Fixed32;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.FocusChangeListener;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.Screen;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.ListField;
import net.rim.device.api.ui.component.ListFieldCallback;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
public class categoryView extends MainScreen implements FieldChangeListener, ListFieldCallback, FocusChangeListener {
private HorizontalFieldManager _top;
private HorizontalFieldManager _nav;
private VerticalFieldManager _middle;
private int horizontalOffset;
private final static long animationTime = 300;
private long animationStart = 0;
private int venue_id;
private int category_id;
private CustomButtonField rectangle;
private Vector venueList = new Vector();
private Hashtable venue_index = new Hashtable();
private Vector image_index = new Vector();
private ListField listField;
private int last_menu_item = 2;
private int last_nav = 2;
private int before_last = 1;
private int location_count = 0;
private int img_width = 120;
private int img_height = 80;
private Field f;
public categoryView(int id) {
super();
category_id = id;
horizontalOffset = Display.getWidth();
_top = new HorizontalFieldManager(Manager.USE_ALL_WIDTH | Field.FIELD_HCENTER)
{
public void paint(Graphics gr)
{
Bitmap bg = Bitmap.getBitmapResource("bg.png");
gr.drawBitmap(0, 0, Display.getWidth(), Display.getHeight(), bg, 0, 0);
subpaint(gr);
}
};
_nav = new HorizontalFieldManager(Field.USE_ALL_WIDTH);
_middle = new VerticalFieldManager();
add(_top);
add(_nav);
add(_middle);
Bitmap lol = Bitmap.getBitmapResource("logo.png");
BitmapField lolfield = new BitmapField(lol);
_top.add(lolfield);
HorizontalFieldManager nav = new HorizontalFieldManager(Field.USE_ALL_WIDTH | Manager.HORIZONTAL_SCROLL);
Vector locs = getLocations();
Hashtable locations = (Hashtable) locs.elementAt(0);
Enumeration ne = locations.keys();
Enumeration nv = locations.elements();
int counter = 1;
if(locations.size() > 1)
{
counter = locations.size() - 1;
}
int count = 1;
while(ne.hasMoreElements())
{
final String location_id = ne.nextElement().toString();
String location = nv.nextElement().toString();
last_nav = Integer.parseInt(location_id);
rectangle = new CustomButtonField(location_id, location, 25, Field.FOCUSABLE);
rectangle.setFocusListener(this);
nav.add(rectangle);
if(count == counter)
{
before_last = Integer.parseInt(location_id);
}
count ++;
}
_nav.add(nav);
}
public void setDefaultLocation()
{
Vector locs = getLocations();
Hashtable loc1 = (Hashtable) locs.elementAt(0);
Enumeration er = loc1.keys();
Enumeration vr = loc1.elements();
int i = 0;
while(er.hasMoreElements())
{
final String location_id = er.nextElement().toString();
if(i == 0)
{
last_menu_item = Integer.parseInt(location_id);
}
i ++;
}
}
public void drawMiddle()
{
Vector venues = getVenues(category_id);
Hashtable venue_list = (Hashtable) venues.elementAt(0);
Enumeration e = venue_list.keys();
Enumeration v = venue_list.elements();
int count = 0;
while(e.hasMoreElements())
{
String vid = e.nextElement().toString();
Hashtable elm = (Hashtable)v.nextElement();
venueList.addElement(elm);
venue_index.put(Integer.toString(count), (String) elm.get("venue_id"));
EncodedImage img = null;
String image_url = (String) elm.get("image_url");
try
{
String filename;
if(image_url.length() > 5)
{
filename = image_url.substring( image_url.indexOf("crop/") + 5, image_url.length() );
}
else
{
filename = "1.png";
}
FileConnection fconn = (FileConnection) Connector.open( "file:///SDCard/Blackberry/venue/" + filename, Connector.READ);
if ( !fconn.exists() )
{
}
else
{
InputStream input = fconn.openInputStream();
byte[] data = new byte[(int)fconn.fileSize()];
input.read(data);
input.close();
if(data.length > 0)
{
EncodedImage rawimg = EncodedImage.createEncodedImage(data, 0, data.length);
int dw = Fixed32.toFP(Display.getWidth());
int iw = Fixed32.toFP(rawimg.getWidth());
int sf = Fixed32.div(iw, dw);
img = rawimg.scaleImage32(sf * 4, sf * 4);
img_width = (int) Math.ceil(Display.getWidth() / 4);
img_height = (int) Math.ceil(Display.getWidth() / 6);
}
else
{
}
}
}
catch(IOException ef)
{
}
image_index.addElement(img);
count ++;
}
final int count_results = count;
_middle = new VerticalFieldManager( Manager.VERTICAL_SCROLLBAR )
{
public void paint(Graphics graphics)
{
graphics.setBackgroundColor(0xFFFFFF);
graphics.setColor(Color.BLACK);
graphics.clear();
super.paint(graphics);
}
protected void sublayout(int maxWidth, int maxHeight)
{
int displayWidth = Display.getWidth();
//int displayHeight = Display.getHeight();
int displayHeight = count_results * img_height;
super.sublayout( displayWidth, displayHeight);
setExtent( displayWidth, displayHeight);
}
};
add(_middle);
listField = new ListField( venueList.size() );
listField.setCallback( this );
listField.setSelectedIndex(-1);
listField.setRowHeight(img_height);
_middle.add( listField );
_middle.add(new RichTextField(Field.NON_FOCUSABLE));
}
public boolean navigationClick(int status, int time) {
Field focus = UiApplication.getUiApplication().getActiveScreen() .getLeafFieldWithFocus();
if (focus instanceof ListField) {
int selected = listField.getSelectedIndex();
String venue_id = (String) venue_index.get(Integer.toString(selected));
moveScreens(venue_id);
}
return true;
}
void setListSize()
{
listField.setSize( venueList.size() );
}
public void drawListRow( ListField listField, Graphics graphics, int index, int y, int width )
{
Hashtable item = (Hashtable) venueList.elementAt( index );
String venue_name = (String) item.get("name");
String address = (String) item.get("address");
String city = (String) item.get("city");
String zip = (String) item.get("zip");
EncodedImage img = (EncodedImage) image_index.elementAt(index);
graphics.drawText( venue_name, img_width + 10, y, 0, width );
graphics.drawText( address, img_width + 10, y + 15, 0, width );
graphics.drawText( city + ", " + zip, img_width + 10, y + 30, 0, width );
if(img != null)
{
graphics.drawImage(0, y + 3, img.getWidth(), img.getHeight(), img, 0, 0, 0);
}
}
public Object get( ListField listField, int index )
{
return venueList.elementAt( index );
}
public Vector getCategories()
{
Vector results = new Vector();
database db = new database();
Vector categories = db.getCategories();
if(categories.size() > 0)
results = categories;
return results;
}
public Vector getLocations()
{
Vector results = new Vector();
database db = new database();
Vector subcats = db.getCategoryLocations(category_id);
Hashtable subs = (Hashtable) subcats.elementAt(0);
if(subs.size() > 0)
{
location_count = subs.size();
results = subcats;
}
return results;
}
public Vector getVenues(int category_id)
{
Vector results = new Vector();
database db = new database();
Vector venues = db.getLocationVenues(category_id, last_menu_item);
if(venues.size() > 0)
results = venues;
return results;
}
protected void makeMenu(Menu menu, int instance)
{
super.makeMenu(menu, instance);
menu.add(new MenuItem("Home", 10, 20){
public void run()
{
moveScreens("main");
}
});
menu.add(new MenuItem("Search", 10, 20){
public void run()
{
Dialog.inform("Search was clicked.");
}
});
Vector locs = getLocations();
Hashtable locations = (Hashtable) locs.elementAt(0);
Enumeration e = locations.keys();
Enumeration v = locations.elements();
while(e.hasMoreElements())
{
final String location_id = e.nextElement().toString();
String location = v.nextElement().toString();
menu.add(new MenuItem(location, 10, 20){
public void run()
{
Dialog.inform("Location " + location_id + " was clicked");
}
});
}
}
public void moveScreens(String type)
{
if(type == "main")
{
UiApplication.getUiApplication().popScreen(this);
}
else
{
int venue_id = Integer.parseInt(type);
Screen newScreen = new ViewVenue(venue_id);
UiApplication.getUiApplication().pushScreen(newScreen);
}
}
protected void sublayout(int width, int height)
{
super.sublayout(width, height);
if(horizontalOffset > 0)
{
if(animationStart == 0)
{
animationStart = System.currentTimeMillis();
}
else
{
long timeElapsed = System.currentTimeMillis() - animationStart;
if(timeElapsed >= animationTime)
{
horizontalOffset = 0;
}
else
{
float percentDone = (float)timeElapsed / (float)animationTime;
horizontalOffset = Display.getWidth() - (int)(percentDone * Display.getWidth());
}
}
}
setPosition(horizontalOffset, 0);
if(horizontalOffset > 0)
{
UiApplication.getUiApplication().invokeLater(new Runnable(){
public void run()
{
updateLayout();
}
});
}
}
public void fieldChanged(Field field, int context)
{
int id = 0;
if (field instanceof CustomButtonField) {
id = ((CustomButtonField)field).getId();
}
venue_id = id;
Dialog.inform(Integer.toString(venue_id));
//moveScreens("venue");
}
public void focusChanged(Field field, int eventType) {
if((eventType == FocusChangeListener.FOCUS_GAINED)) {
if (field instanceof CustomButtonField) {
final int id = ((CustomButtonField)field).getId();
if(id == last_nav && before_last != last_menu_item && last_nav != before_last)
{
//updateContent(id);
f.setFocus();
}
else
{
updateContent(id);
f = field;
}
}
}
}
public void updateContent(final int id)
{
UiApplication.getUiApplication().invokeLater(new Runnable(){
public void run()
{
delete(_middle);
venueList.removeAllElements();
image_index.removeAllElements();
last_menu_item = id;
drawMiddle();
}
});
}
public boolean onSavePrompt()
{
// do nothing
return true;
}
public int getPreferredWidth(ListField listField) {
// TODO Auto-generated method stub
return 0;
}
public int indexOfList(ListField listField, String prefix, int start) {
// TODO Auto-generated method stub
return 0;
}
}