JCUDA cuda file not compiling - java

http://www.jcuda.org/tutorial/TutorialIndex.html
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package jcudavectoradd;
/**
*
* #author Sanjula
*/
/*
* JCuda - Java bindings for NVIDIA CUDA driver and runtime API
* http://www.jcuda.org
*
* Copyright 2011 Marco Hutter - http://www.jcuda.org
*/
import static jcuda.driver.JCudaDriver.*;
import java.io.*;
import jcuda.*;
import jcuda.driver.*;
/**
* This is a sample class demonstrating how to use the JCuda driver
* bindings to load and execute a CUDA vector addition kernel.
* The sample reads a CUDA file, compiles it to a PTX file
* using NVCC, loads the PTX file as a module and executes
* the kernel function. <br />
*/
public class JCudaVectorAdd
{
/**
* Entry point of this sample
*
* #param args Not used
* #throws IOException If an IO error occurs
*/
public static void main(String args[]) throws IOException
{
// Enable exceptions and omit all subsequent error checks
JCudaDriver.setExceptionsEnabled(true);
// Create the PTX file by calling the NVCC
String ptxFileName = preparePtxFile("JCudaVectorAddKernel.cu");
//String ptxFileName = "JCudaVectorAddKernel.ptx";
// Initialize the driver and create a context for the first device.
cuInit(0);
CUdevice device = new CUdevice();
cuDeviceGet(device, 0);
CUcontext context = new CUcontext();
cuCtxCreate(context, 0, device);
// Load the ptx file.
CUmodule module = new CUmodule();
cuModuleLoad(module, ptxFileName);
// Obtain a function pointer to the "add" function.
CUfunction function = new CUfunction();
cuModuleGetFunction(function, module, "add");
int numElements = 100000;
// Allocate and fill the host input data
float hostInputA[] = new float[numElements];
float hostInputB[] = new float[numElements];
for(int i = 0; i < numElements; i++)
{
hostInputA[i] = (float)i;
hostInputB[i] = (float)i;
}
// Allocate the device input data, and copy the
// host input data to the device
CUdeviceptr deviceInputA = new CUdeviceptr();
cuMemAlloc(deviceInputA, numElements * Sizeof.FLOAT);
cuMemcpyHtoD(deviceInputA, Pointer.to(hostInputA),
numElements * Sizeof.FLOAT);
CUdeviceptr deviceInputB = new CUdeviceptr();
cuMemAlloc(deviceInputB, numElements * Sizeof.FLOAT);
cuMemcpyHtoD(deviceInputB, Pointer.to(hostInputB),
numElements * Sizeof.FLOAT);
// Allocate device output memory
CUdeviceptr deviceOutput = new CUdeviceptr();
cuMemAlloc(deviceOutput, numElements * Sizeof.FLOAT);
// Set up the kernel parameters: A pointer to an array
// of pointers which point to the actual values.
Pointer kernelParameters = Pointer.to(
Pointer.to(new int[]{numElements}),
Pointer.to(deviceInputA),
Pointer.to(deviceInputB),
Pointer.to(deviceOutput)
);
// Call the kernel function.
int blockSizeX = 256;
int gridSizeX = (int)Math.ceil((double)numElements / blockSizeX);
cuLaunchKernel(function,
gridSizeX, 1, 1, // Grid dimension
blockSizeX, 1, 1, // Block dimension
0, null, // Shared memory size and stream
kernelParameters, null // Kernel- and extra parameters
);
cuCtxSynchronize();
// Allocate host output memory and copy the device output
// to the host.
float hostOutput[] = new float[numElements];
cuMemcpyDtoH(Pointer.to(hostOutput), deviceOutput,
numElements * Sizeof.FLOAT);
// Verify the result
boolean passed = true;
for(int i = 0; i < numElements; i++)
{
float expected = i+i;
if (Math.abs(hostOutput[i] - expected) > 1e-5)
{
System.out.println(
"At index "+i+ " found "+hostOutput[i]+
" but expected "+expected);
passed = false;
break;
}
}
System.out.println("Test "+(passed?"PASSED":"FAILED"));
// Clean up.
cuMemFree(deviceInputA);
cuMemFree(deviceInputB);
cuMemFree(deviceOutput);
}
/**
* The extension of the given file name is replaced with "ptx".
* If the file with the resulting name does not exist, it is
* compiled from the given file using NVCC. The name of the
* PTX file is returned.
*
* #param cuFileName The name of the .CU file
* #return The name of the PTX file
* #throws IOException If an I/O error occurs
*/
private static String preparePtxFile(String cuFileName) throws IOException
{
int endIndex = cuFileName.lastIndexOf('.');
if (endIndex == -1)
{
endIndex = cuFileName.length()-1;
}
String ptxFileName = cuFileName.substring(0, endIndex+1)+"ptx";
File ptxFile = new File(ptxFileName);
if (ptxFile.exists())
{
return ptxFileName;
}
File cuFile = new File(cuFileName);
if (!cuFile.exists())
{
throw new IOException("Input file not found: "+cuFileName);
}
String modelString = "-m"+System.getProperty("sun.arch.data.model");
String command =
"nvcc " + modelString + " -ptx "+
cuFile.getPath()+" -o "+ptxFileName;
System.out.println("Executing\n"+command);
Process process = Runtime.getRuntime().exec(command);
String errorMessage =
new String(toByteArray(process.getErrorStream()));
String outputMessage =
new String(toByteArray(process.getInputStream()));
int exitValue = 0;
try
{
exitValue = process.waitFor();
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
throw new IOException(
"Interrupted while waiting for nvcc output", e);
}
if (exitValue != 0)
{
System.out.println("nvcc process exitValue "+exitValue);
System.out.println("errorMessage:\n"+errorMessage);
System.out.println("outputMessage:\n"+outputMessage);
throw new IOException(
"Could not create .ptx file: "+errorMessage);
}
System.out.println("Finished creating PTX file");
return ptxFileName;
}
/**
* Fully reads the given InputStream and returns it as a byte array
*
* #param inputStream The input stream to read
* #return The byte array containing the data from the input stream
* #throws IOException If an I/O error occurs
*/
private static byte[] toByteArray(InputStream inputStream)
throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buffer[] = new byte[8192];
while (true)
{
int read = inputStream.read(buffer);
if (read == -1)
{
break;
}
baos.write(buffer, 0, read);
}
return baos.toByteArray();
}
}
extern "C"
__global__ void add(int n, float *a, float *b, float *sum)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i<n)
{
sum[i] = a[i] + b[i];
}
}
when I compile this code I get this error. I am using the NetBeans 8.2 and I installed the Cuda. it is perfectly working in the visual studio 2015 . but it not working with java.

i added visual studio cl.exe path to Environment Variables
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin
go to My Computer -> Properties -> Advanced System Settings -> Environment Variables. Here look for "PATH" in the list, and add the path above (or whatever is the location of your cl.exe).

Related

timestamp as file name in java

I need to create a text file in the name of current timestamp in a particular directory
D:\Assignments\abassign in java.
But when i try to do that the following error comes as the file name should not contain ':'. But the timestamp contains ':'
Exception in thread "main" java.io.IOException: The filename, directory name, or volume label syntax is incorrect
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:883)
at abassign.Abassign.main(Abassign.java:35)
Java Result: 1
This error shows up
I use something like this:
StringBuffer fn = new StringBuffer();
fn.append(workingDirectory);
fn.append("/");
fn.append("fileNamePrefix-");
fn.append("-");
DateFormat df = new SimpleDateFormat("yyyyMMdd-HHmmss");
fn.append(df.format(new Date()));
fn.append("-fileNamePostFix.txt");
return fn.toString();
(Of course, you can drop the prefix, postfix and workingDirectory parts)
If you are on Windows your file name cannot contain :, you need to replace it by another character...
The following characters are reserved :
< (less than)
> (greater than)
: (colon)
" (double quote)
/ (forward slash)
\ (backslash)
| (vertical bar or pipe)
? (question mark)
* (asterisk)
For example :
String yourTimeStamp = "01-01-2016 17:00:00";
File yourFile = new File("your directory", yourTimeStamp.replace(":", "_"));
here is the Code to generate file using time stamp
/*
* created by Sandip Bhoi 9960426568
*/
package checkapplicationisopen;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Random;
public class GeneratorUtil {
/**
*
* #param args
*/
public static void main(String args[])
{
GeneratorUtil generatorUtil=new GeneratorUtil();
generatorUtil.createNewFile("c:\\Documents", "pdf");
}
/**
*
* #param min
* #param max
* #return
*/
public static int randInt(int min, int max) {
// Usually this can be a field rather than a method variable
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
/**
*
* #param prefix adding the prefix for time stamp generated id
* #return the concatenated string with id and prefix
*/
public static String getId(String prefix)
{
java.util.Date date = new java.util.Date();
String timestamp = new Timestamp(date.getTime()).toString();
String dt1 = timestamp.replace('-', '_');
String dt2 = dt1.replace(' ', '_');
String dt3 = dt2.replace(':', '_');
String dt4 = dt3.replace('.', '_');
int temp = randInt(1, 5000);
return prefix +"_"+ temp + "_" + dt4;
}
/**
*
* #param direcotory
* #param extension
*/
public void createNewFile(String direcotory,String extension)
{
try {
File file = new File(direcotory+"//"+getId("File")+"."+extension);
if (file.createNewFile()){
System.out.println("File is created!");
}else{
System.out.println("File already exists.");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Rectify Exception in JSpeex Encoding

I am getting a null pointer exception. I have seen the previous posts for null pointer exception but I am unable to solve my problem. Also I provided my snapshot of the Exception
Below is my JSpeexCode and SpeexEncoder code.
JSpeex Code
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.xiph.speex.AudioFileWriter;
import org.xiph.speex.OggSpeexWriter;
import org.xiph.speex.PcmWaveWriter;
import org.xiph.speex.RawWriter;
import org.xiph.speex.SpeexEncoder;
/**
* Java Speex Command Line Encoder.
*
* Currently this code has been updated to be compatible with release 1.0.3.
*
* #author Marc Gimpel, Wimba S.A. (mgimpel#horizonwimba.com)
* #version $Revision: 1.5 $
*/
public class JSpeexEnc
{
/** Version of the Speex Encoder */
public static final String VERSION = "Java Speex Command Line Encoder v0.9.7 ($Revision: 1.5 $)";
/** Copyright display String */
public static final String COPYRIGHT = "Copyright (C) 2002-2004 Wimba S.A.";
/** Print level for messages : Print debug information */
public static final int DEBUG = 0;
/** Print level for messages : Print basic information */
public static final int INFO = 1;
/** Print level for messages : Print only warnings and errors */
public static final int WARN = 2;
/** Print level for messages : Print only errors */
public static final int ERROR = 3;
/** Print level for messages */
protected int printlevel = INFO;
/** File format for input or output audio file: Raw */
public static final int FILE_FORMAT_RAW = 0;
/** File format for input or output audio file: Ogg */
public static final int FILE_FORMAT_OGG = 1;
/** File format for input or output audio file: Wave */
public static final int FILE_FORMAT_WAVE = 2;
/** Defines File format for input audio file (Raw, Ogg or Wave). */
protected int srcFormat = FILE_FORMAT_OGG;
/** Defines File format for output audio file (Raw or Wave). */
protected int destFormat = FILE_FORMAT_WAVE;
/** Defines the encoder mode (0=NB, 1=WB and 2=UWB). */
protected int mode = -1;
/** Defines the encoder quality setting (integer from 0 to 10). */
protected int quality = 8;
/** Defines the encoders algorithmic complexity. */
protected int complexity = 3;
/** Defines the number of frames per speex packet. */
protected int nframes = 1;
/** Defines the desired bitrate for the encoded audio. */
protected int bitrate = -1;
/** Defines the sampling rate of the audio input. */
protected int sampleRate = -1;
/** Defines the number of channels of the audio input (1=mono, 2=stereo). */
protected int channels = 1;
/** Defines the encoder VBR quality setting (float from 0 to 10). */
protected float vbr_quality = -1;
/** Defines whether or not to use VBR (Variable Bit Rate). */
protected boolean vbr = false;
/** Defines whether or not to use VAD (Voice Activity Detection). */
protected boolean vad = false;
/** Defines whether or not to use DTX (Discontinuous Transmission). */
protected boolean dtx = false;
/** The audio input file */
protected String srcFile;
/** The audio output file */
protected String destFile;
/**
* Builds a plain JSpeex Encoder with default values.
*/
/**
* Command line entrance:
* <pre>
* Usage: JSpeexEnc [options] input_file output_file
* </pre>
* #param args Command line parameters.
*/
public static void main(final String[] args) throws IOException
{
JSpeexEnc encoder = new JSpeexEnc();
if (encoder.parseArgs(args)) {
encoder.encode("frf1.wav", "frf1_encoded.raw");
try (BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\Administrator\\workspace\\JSpeex.java\\src\\frf1.wav")))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}
} catch (FileNotFoundException e) {
}
}
}
/**
* Parse the command line arguments.
* #param args Command line parameters.
* #param FILE_FORMAT_WAVE1
* #return true if the parsed arguments are sufficient to run the encoder.
*/
public boolean parseArgs(final String[] args)
{
// make sure we have command args
if (args.length < 2) {
if (args.length==1 && (args[0].equalsIgnoreCase("-v") || args[0].equalsIgnoreCase("--version"))) {
version();
return false;
}
usage();
return false;
}
// Determine input, output and file formats
srcFile = args[args.length-2];
destFile = args[args.length-1];
if (srcFile.toLowerCase().endsWith(".wav"))
{
srcFormat = FILE_FORMAT_WAVE;
}
else {
srcFormat = FILE_FORMAT_RAW;
}
if (destFile.toLowerCase().endsWith(".spx")) {
destFormat = FILE_FORMAT_OGG;
}
else if (destFile.toLowerCase().endsWith(".wav")) {
destFormat = FILE_FORMAT_WAVE;
}
else {
destFormat = FILE_FORMAT_RAW;
}
// Determine encoder options
for (int i=0; i<args.length-2; i++) {
if (args[i].equalsIgnoreCase("-h") || args[i].equalsIgnoreCase("--help")) {
usage();
return false;
}
else if (args[i].equalsIgnoreCase("-v") || args[i].equalsIgnoreCase("--version")) {
version();
return false;
}
else if (args[i].equalsIgnoreCase("--verbose")) {
printlevel = DEBUG;
}
else if (args[i].equalsIgnoreCase("--quiet")) {
printlevel = WARN;
}
else if (args[i].equalsIgnoreCase("-n") ||
args[i].equalsIgnoreCase("-nb") ||
args[i].equalsIgnoreCase("--narrowband")) {
mode = 0;
}
else if (args[i].equalsIgnoreCase("-w") ||
args[i].equalsIgnoreCase("-wb") ||
args[i].equalsIgnoreCase("--wideband")) {
mode = 1;
}
else if (args[i].equalsIgnoreCase("-u") ||
args[i].equalsIgnoreCase("-uwb") ||
args[i].equalsIgnoreCase("--ultra-wideband")) {
mode = 2;
}
else if (args[i].equalsIgnoreCase("-q") || args[i].equalsIgnoreCase("--quality")) {
try {
vbr_quality = Float.parseFloat(args[++i]);
quality = (int) vbr_quality;
}
catch (NumberFormatException e) {
usage();
return false;
}
}
else if (args[i].equalsIgnoreCase("--complexity")) {
try {
complexity = Integer.parseInt(args[++i]);
}
catch (NumberFormatException e) {
usage();
return false;
}
}
else if (args[i].equalsIgnoreCase("--nframes")) {
try {
nframes = Integer.parseInt(args[++i]);
}
catch (NumberFormatException e) {
usage();
return false;
}
}
else if (args[i].equalsIgnoreCase("--vbr")) {
vbr = true;
}
else if (args[i].equalsIgnoreCase("--vad")) {
vad = true;
}
else if (args[i].equalsIgnoreCase("--dtx")) {
dtx = true;
}
else if (args[i].equalsIgnoreCase("--rate")) {
try {
sampleRate = Integer.parseInt(args[++i]);
}
catch (NumberFormatException e) {
usage();
return false;
}
}
else if (args[i].equalsIgnoreCase("--stereo")) {
channels = 2;
}
else {
usage();
return false;
}
}
return true;
}
/**
* Prints the usage guidelines.
*/
public static void usage()
{
version();
System.out.println("");
System.out.println("Usage: JSpeexEnc [options] input_file output_file");
System.out.println("Where:");
System.out.println(" input_file can be:" );
System.out.println(" filename.wav a PCM wav file");
System.out.println(" filename.* a raw PCM file (any extension other than .wav)");
System.out.println(" output_file can be:");
System.out.println(" filename.spx an Ogg Speex file");
System.out.println(" filename.wav a Wave Speex file (beta!!!)");
System.out.println(" filename.* a raw Speex file");
System.out.println("Options: -h, --help This help");
System.out.println(" -v, --version Version information");
System.out.println(" --verbose Print detailed information");
System.out.println(" --quiet Print minimal information");
System.out.println(" -n, -nb Consider input as Narrowband (8kHz)");
System.out.println(" -w, -wb Consider input as Wideband (16kHz)");
System.out.println(" -u, -uwb Consider input as Ultra-Wideband (32kHz)");
System.out.println(" --quality n Encoding quality (0-10) default 8");
System.out.println(" --complexity n Encoding complexity (0-10) default 3");
System.out.println(" --nframes n Number of frames per Ogg packet, default 1");
System.out.println(" --vbr Enable varible bit-rate (VBR)");
System.out.println(" --vad Enable voice activity detection (VAD)");
System.out.println(" --dtx Enable file based discontinuous transmission (DTX)");
System.out.println(" if the input file is raw PCM (not a Wave file)");
System.out.println(" --rate n Sampling rate for raw input");
System.out.println(" --stereo Consider input as stereo");
System.out.println("More information is available from: http://jspeex.sourceforge.net/");
System.out.println("This code is a Java port of the Speex codec: http://www.speex.org/");
}
/**
* Prints the version.
*/
public static void version()
{
System.out.println(VERSION);
System.out.println("using " + SpeexEncoder.VERSION);
System.out.println(COPYRIGHT);
}
/**
* Encodes a PCM file to Speex.
*/
public void encode()
{
System.out.println("Value of Destination File is:= "+destFile);
encode();
System.out.println("Value of Destination File is:= " +srcFile +destFile);
}
/**
* Encodes a PCM file to Speex.
* #param string
* #param string2
* #exception IOException */
public void encode(final String string, final String string2)throws IOException
{
byte[] temp = new byte[2560]; // stereo UWB requires one to read 2560b
final int HEADERSIZE = 8;
final String RIFF = "RIFF";
final String WAVE = "WAVE";
final String FORMAT = "fmt ";
final String DATA = "data";
final int WAVE_FORMAT_PCM = 0x0001;
// Display info
if (printlevel <= INFO) {
version();
}
if (printlevel <= DEBUG) {
System.out.println("");
}
if (printlevel <= DEBUG) {
System.out.println("Input File: " );
}
try
(DataInputStream dis = new DataInputStream(new FileInputStream(string)))
{
if (srcFormat == FILE_FORMAT_WAVE) {
// read the WAVE header
dis.readFully(temp, 0, HEADERSIZE+4);
// make sure its a WAVE header
if (!RIFF.equals(new String(temp, 0, 4)) &&
!WAVE.equals(new String(temp, 8, 4)))
{
System.err.println("Not a WAVE file");
return;
}
// Read other header chunks
dis.readFully(temp, 0, HEADERSIZE);
String chunk = new String(temp, 0, 4);
int size = readInt(temp, 4);
while (!chunk.equals(DATA)) {
dis.readFully(temp, 0, size);
if (chunk.equals(FORMAT)) {
/*
typedef struct waveformat_extended_tag {
WORD wFormatTag; // format type
WORD nChannels; // number of channels (i.e. mono, stereo...)
DWORD nSamplesPerSec; // sample rate
DWORD nAvgBytesPerSec; // for buffer estimation
WORD nBlockAlign; // block size of data
WORD wBitsPerSample; // Number of bits per sample of mono data
WORD cbSize; // The count in bytes of the extra size
} WAVEFORMATEX;
*/
if (readShort(temp, 0) != WAVE_FORMAT_PCM) {
System.err.println("Not a PCM file");
return;
}
channels = readShort(temp, 2);
sampleRate = readInt(temp, 4);
if (readShort(temp, 14) != 16) {
System.err.println("Not a 16 bit file " + readShort(temp, 18));
return;
}
// Display audio info
if (printlevel <= DEBUG) {
System.out.println("File Format: PCM wave");
System.out.println("Sample Rate: " + sampleRate);
System.out.println("Channels: " + channels);
}
}
dis.readFully(temp, 0, HEADERSIZE);
chunk = new String(temp, 0, 4);
size = readInt(temp, 4);
}
if (printlevel <= DEBUG) {
System.out.println("Data size: " + size);
}
}
else {
if (sampleRate < 0) {
switch (mode) {
case 0:
sampleRate = 8000;
break;
case 1:
sampleRate = 16000;
break;
case 2:
sampleRate = 32000;
break;
default:
sampleRate = 8000;
break;
}
}
// Display audio info
if (printlevel <= DEBUG) {
System.out.println("File format: Raw audio");
System.out.println("Sample rate: " + sampleRate);
System.out.println("Channels: " + channels);
System.out.println("Data size: " + string.length());
}
}
// Set the mode if it has not yet been determined
if (mode < 0) {
if (sampleRate < 100) { // Sample Rate has probably been given in kHz
sampleRate *= 1000;
}
if (sampleRate < 12000) {
mode = 0; // Narrowband
} else if (sampleRate < 24000) {
mode = 1; // Wideband
} else {
mode = 2; // Ultra-wideband
}
}
// Construct a new encoder
SpeexEncoder speexEncoder = new SpeexEncoder();
SpeexEncoder speexEncoder1 = speexEncoder;
if (complexity > 0) {
speexEncoder1.setComplexity(complexity);
}
if (bitrate > 0) {
speexEncoder1.setBitRate(bitrate);
// speexEncoder1.getEncoder().setBitRate(bitrate);
}
if (vbr) {
// speexEncoder1.getEncoder().setVbr(vbr);
if (vbr_quality > 0) {
speexEncoder1.setVbrQuality(vbr_quality);
}
}
if (vad) {
( speexEncoder1).setVad(vad);
}
if (dtx) {
( speexEncoder1).setDtx(dtx);
}
// Display info
if (printlevel <= DEBUG) {
System.out.println("");
System.out.println("Output File: " + string2);
System.out.println("File format: Ogg Speex");
System.out.println("Encoder mode: " + (mode==0 ? "Narrowband" : (mode==1 ? "Wideband" : "UltraWideband")));
System.out.println("Quality: " + (vbr ? vbr_quality : quality));
System.out.println("Complexity: " + complexity);
System.out.println("Frames per packet: " + nframes);
System.out.println("Variable bitrate: " + vbr);
System.out.println("Voice activity detection: " + vad);
System.out.println("Discontinouous Transmission: " + dtx);
}
// Open the file writer
AudioFileWriter writer;
if (destFormat == FILE_FORMAT_OGG) {
writer = new OggSpeexWriter(mode, sampleRate, channels, nframes, vbr);
}
else if (destFormat == FILE_FORMAT_WAVE) {
nframes = PcmWaveWriter.WAVE_FRAME_SIZES[mode-1][channels-1][quality];
writer = new PcmWaveWriter(mode, quality, sampleRate, channels, nframes, vbr);
}
else {
writer = new RawWriter();
}
writer.open(string2);
writer.writeHeader("Encoded with: " + VERSION);
int pcmPacketSize = 2 * channels * speexEncoder.getFrameSize();
while (true) {
dis.readFully(temp, 0, nframes*pcmPacketSize);
for (int i=0; i<nframes; i++)
speexEncoder.processData(temp, i*pcmPacketSize, pcmPacketSize);
int encsize = speexEncoder.getProcessedData(temp, 0);
if (encsize > 0) {
writer.writePacket(temp, 0, encsize);
}
}
}
}
/**
* Converts Little Endian (Windows) bytes to an int (Java uses Big Endian).
* #param data the data to read.
* #param offset the offset from which to start reading.
* #return the integer value of the reassembled bytes.
*/
protected static int readInt(final byte[] data, final int offset)
{
return (data[offset] & 0xff) |
((data[offset+1] & 0xff) << 8) |
((data[offset+2] & 0xff) << 16) |
(data[offset+3] << 24); // no 0xff on the last one to keep the sign
}
/**
* Converts Little Endian (Windows) bytes to an short (Java uses Big Endian).
* #param data the data to read.
* #param offset the offset from which to start reading.
* #return the integer value of the reassembled bytes.
*/
protected static int readShort(final byte[] data, final int offset)
{
return (data[offset] & 0xff) |
(data[offset+1] << 8); // no 0xff on the last one to keep the sign
}
}
SpeexEncoder code
package org.xiph.speex;
/**
* Main Speex Encoder class.
* This class encodes the given PCM 16bit samples into Speex packets.
*
* #author Marc Gimpel, Wimba S.A. (mgimpel#horizonwimba.com)
* #version $Revision: 1.6 $
*/
public class SpeexEncoder
{
/**
* Version of the Speex Encoder
*/
public static final String VERSION = "Java Speex Encoder v0.9.7 ($Revision: 1.6 $)";
private Encoder encoder;
private Bits bits;
private float[] rawData;
private int sampleRate;
private int channels;
private int frameSize;
/**
* Constructor
*/
public SpeexEncoder()
{
bits = new Bits();
}
/**
* Initialisation
* #param mode the mode of the encoder (0=NB, 1=WB, 2=UWB).
* #param quality the quality setting of the encoder (between 0 and 10).
* #param sampleRate the number of samples per second.
* #param channels the number of audio channels (1=mono, 2=stereo, ...).
* #return true if initialisation successful.
*/
public boolean init(final int mode,
final int quality,
final int sampleRate,
final int channels)
{
switch (mode) {
case 0:
encoder = new NbEncoder();
((NbEncoder)encoder).nbinit();
break;
//Wideband
case 1:
encoder = new SbEncoder();
((SbEncoder)encoder).wbinit();
break;
case 2:
encoder = new SbEncoder();
((SbEncoder)encoder).uwbinit();
break;
//*/
default:
return false;
}
/* initialize the speex decoder */
encoder.setQuality(quality);
/* set decoder format and properties */
this.frameSize = encoder.getFrameSize();
this.sampleRate = sampleRate;
this.channels = channels;
rawData = new float[channels*frameSize];
bits.init();
return true;
}
/**
* Returns the Encoder being used (Narrowband, Wideband or Ultrawideband).
* #return the Encoder being used (Narrowband, Wideband or Ultrawideband).
*/
public Encoder getEncoder()
{
return encoder;
}
/**
* Returns the sample rate.
* #return the sample rate.
*/
public int getSampleRate()
{
return sampleRate;
}
/**
* Returns the number of channels.
* #return the number of channels.
*/
public int getChannels()
{
return channels;
}
/**
* Returns the size of a frame.
* #return the size of a frame.
*/
public int getFrameSize()
{
return frameSize;
}
/**
* Pull the decoded data out into a byte array at the given offset
* and returns the number of bytes of encoded data just read.
* #param data
* #param offset
* #return the number of bytes of encoded data just read.
*/
public int getProcessedData(final byte[] data, final int offset)
{
int size = bits.getBufferSize();
System.arraycopy(bits.getBuffer(), 0, data, offset, size);
bits.init();
return size;
}
/**
* Returns the number of bytes of encoded data ready to be read.
* #return the number of bytes of encoded data ready to be read.
*/
public int getProcessedDataByteSize()
{
return bits.getBufferSize();
}
/**
* This is where the actual encoding takes place
* #param data
* #param offset
* #param len
* #return true if successful.
*/
public boolean processData(final byte[] data,
final int offset,
final int len)
{
// converty raw bytes into float samples
mapPcm16bitLittleEndian2Float(data, offset, rawData, len, len);
// encode the bitstream
return processData(rawData, len/2);
}
/**
* Encode an array of shorts.
* #param data
* #param offset
* #param numShorts
* #return true if successful.
*/
public boolean processData(final short[] data,
final int offset,
final int numShorts)
{
int numSamplesRequired = channels * frameSize;
if (numShorts != numSamplesRequired) {
throw new IllegalArgumentException("SpeexEncoder requires " + numSamplesRequired + " samples to process a Frame, not " + numShorts);
}
// convert shorts into float samples,
for (int i=0; i<numShorts; i++) {
rawData[i] = (float) data[offset + i ];
}
// encode the bitstream
return processData(rawData, numShorts);
}
/**
* Encode an array of floats.
* #param data
* #param numSamples
* #return true if successful.
*/
public boolean processData(final float[] data, final int numSamples)
{
int numSamplesRequired = channels * frameSize;
if (numSamples != numSamplesRequired) {
throw new IllegalArgumentException("SpeexEncoder requires " + numSamplesRequired + " samples to process a Frame, not " + numSamples );
}
// encode the bitstream
if (channels==2) {
Stereo.encode(bits, data, frameSize);
}
encoder.encode(bits, data);
//System.out.println("THA VALUE OF BITS IS:" + bits);
return true;
}
/**
* Converts a 16 bit linear PCM stream (in the form of a byte array)
* into a floating point PCM stream (in the form of an float array).
* Here are some important details about the encoding:
* <ul>
* <li> Java uses big endian for shorts and ints, and Windows uses little Endian.
* Therefore, shorts and ints must be read as sequences of bytes and
* combined with shifting operations.
* </ul>
* #param pcm16bitBytes - byte array of linear 16-bit PCM formated audio.
* #param offsetInput
* #param samples - float array to receive the 16-bit linear audio samples.
* #param offsetOutput
* #param length
*/
void mapPcm16bitLittleEndian2Float(final byte[] pcm16bitBytes,
final int offsetInput,
float[] samples,
final int offsetOutput,
final int length)
{
if (pcm16bitBytes.length - offsetInput < 2 * length) {
throw new IllegalArgumentException("Insufficient Samples to convert to floats");
}
System.out.println("the value is:" +samples);
if (samples.length - offsetOutput < length) {
throw new IllegalArgumentException("Insufficient float buffer to convert the samples");
}
for (int i = 0; i < length; i++) {
samples[offsetOutput+i] = (float)((pcm16bitBytes[offsetInput+2*i] & 0xff) | (pcm16bitBytes[offsetInput+2*i+1] << 8)); // no & 0xff at the end to keep the sign
}
}
public void setComplexity(int complexity) {
// TODO Auto-generated method stub
}
public void setVbrQuality(float vbr_quality) {
// TODO Auto-generated method stub
}
public void setDtx(boolean dtx) {
// TODO Auto-generated method stub
}
public void setBitRate(int bitrate) {
// TODO Auto-generated method stub
}
public void setVad(boolean vad) {
// TODO Auto-generated method stub
}
}
Exceptions:
Exception in thread "main" java.lang.NullPointerException
at org.xiph.speex.SpeexEncoder.mapPcm16bitLittleEndian2Float(SpeexEncoder.java:290)
at org.xiph.speex.SpeexEncoder.processData(SpeexEncoder.java:216)
at JSpeexEnc.encode(JSpeexEnc.java:541)
at JSpeexEnc.main(JSpeexEnc.java:170)
Check the sizes of the arrays that you're passing into mapPcm16bitLittleEndian2Float, and the number of iterations that your loops are doing, bearing in mind that in Java, arrays start from zero.

cannot find symbol: variable TestUtils

I have written a Java program that analyze .soft file of data on gene expressions and write it to txt
package il.ac.tau.cs.sw1.bioinformatics;
import org.apache.commons.math3.stat.inference.TestUtils;
import java.io.*;
import java.util.Arrays;
/**
*
* Gene Expression Analyzer
*
* Command line arguments:
* args[0] - GeoDatasetName: Gene expression dataset name (expects a corresponding
input file in SOFT format to exist in the local directory).
* args[1] - Label1: Label of the first sample subset
* args[2] - Label2: Label of the second sample subset
* args[3] - Alpha: T-test confidence level : only genes with pValue below this
threshold will be printed to output file
*
* Execution example: GeneExpressionAnalyzer GDS4085 "estrogen receptor-negative" "estrogen receptor-positive" 0.01
*
* #author software1-2014
*
*/
public class GeneExpressionAnalyzer {
public static void main(String args[]) throws IOException {
// Reads the dataset from a SOFT input file
String inputSoftFileName = args[0] + ".soft";
GeneExpressionDataset geneExpressionDataset = parseGeneExpressionFile (inputSoftFileName);
System.out.printf ("Gene expression dataset loaded from file %s. %n",inputSoftFileName);
System.out.printf("Dataset contains %d samples and %d gene probes.%n%n",geneExpressionDataset.samplesNumber, geneExpressionDataset.genesNumber);
// Writes the dataset to a tabular format
String tabularFileName = args[0] + "-Tabular.txt";
writeDatasetToTabularFile(geneExpressionDataset,tabularFileName);
System.out.printf ("Dataset saved to tabular file - %s.%n%n",tabularFileName);
// Identifies differentially expressed genes between two sample groups and writes the results to a text file
String label1 = args[1];
String label2 = args[2];
double alpha = Double.parseDouble(args[3]);
String diffGenesFileName = args[0] + "-DiffGenes.txt";
int numOfDiffGenes = writeTopDifferentiallyExpressedGenesToFile(diffGenesFileName,geneExpressionDataset, alpha, label1, label2);
System.out.printf ("%d differentially expressed genes identified using alpha of %f when comparing the two sample groups [%s] and [%s].%n",numOfDiffGenes, alpha, label1, label2);
System.out.printf ("Results saved to file %s.%n",diffGenesFileName);
}
private static float[] StringtoFloat(String[] temp) {
float[] array = new float[temp.length];
for (int i = 0; i < temp.length; i++){
array[i]= Float.parseFloat(temp[i]);
}
return array;
}
private static double[] CutToCounter(double[] array, int counter) {
if (array.length == counter){
return array;
}
double[] args = new double[counter+1];
for (int i = 0; i < args.length; i++){
args[i] = array[i];
}
return args;
}
private static int min(double[] pValues) {
double val = 2;
int index = -1;
for (int i = 0; i < pValues.length; i++){
if (pValues[i] < val && pValues[i] != 3.0){
val = pValues[i];
index = i;
}
}
return index;
}
private static String changeformat(float[] array) {
String[] args = new String[array.length];
for (int i = 0; i < array.length; i++){
args[i] = String.format("%.2f", array[i]);
}
return Arrays.toString(args);
}
/**
*
* parseGeneExpressionFile - parses the given SOFT file
*
*
* #param filename A gene expression file in SOFT format
* #return a GeneExpressionDataset object storing all data parsed from the input file
* #throws IOException
*/
public static GeneExpressionDataset parseGeneExpressionFile (String filename) throws IOException {
GeneExpressionDataset dataset = new GeneExpressionDataset();
BufferedReader buf = new BufferedReader(new FileReader(filename));
String line = buf.readLine();
String[] geneids = null;
String[] genesymbols = null;
float[][] datamatrix = null;
String[][] subsetinfo = new String[10][2];
String[][] subsetsample = new String[10][];
int i = 0;
int j = 0;
boolean bol = false;
while (line != null){
if (line.startsWith("!dataset_sample_count")){
dataset.samplesNumber = Integer.parseInt(line.substring(24));
}
else if (line.startsWith("!dataset_sample_count")){
dataset.genesNumber = Integer.parseInt(line.substring(25));
geneids = new String[dataset.genesNumber];
genesymbols = new String[dataset.genesNumber];
}
else if (line.startsWith("^SUBSET")){
subsetinfo[i][0] = line.substring(10);
i++;
}
else if (line.startsWith("!subset_sample_description")){
subsetinfo[i][1] = line.substring(22);
}
else if (line.startsWith("!subset_sample_id")){
subsetsample[i-1] = line.substring(20).split(",");
}
else if (line.startsWith("!dataset_table_begin")){
datamatrix = new float[dataset.genesNumber][dataset.samplesNumber];
}
else if (line.startsWith("ID_REF")){
String[] array1 = line.split("\t");
dataset.sampleIds = (String[]) Arrays.copyOfRange(array1, 2, array1.length);
bol = true;
}
else if (bol && !line.startsWith("!dataset_table_end")){
String[] array2 = line.split("\t");
geneids[j] = array2[0];
genesymbols[j] = array2[1];
String[] temp = (String[]) Arrays.copyOfRange(array2, 2, array2.length);
datamatrix[j] = StringtoFloat(temp);
j++;
}
}
buf.close();
dataset.geneIds = geneids;
dataset.geneSymbols = genesymbols;
dataset.dataMatrix = datamatrix;
String[] lables = new String[dataset.samplesNumber];
int k = 0;
for (String sample : dataset.sampleIds) {
for (int m = 0; m < subsetsample.length; m++) {
if (Arrays.binarySearch(subsetsample[m], sample) != -1) {
lables[k] = subsetsample[m][1];
k += 1;
} else {
continue;
}
}
}
dataset.labels = lables;
return dataset;
}
/**
* writeDatasetToTabularFile
* writes the dataset to a tabular text file
*
* #param geneExpressionDataset
* #param outputFilename
* #throws IOException
*/
public static void writeDatasetToTabularFile(GeneExpressionDataset geneExpressionDataset, String outputFilename) throws IOException {
File NewFile = new File(outputFilename);
BufferedWriter buf = new BufferedWriter(new FileWriter(NewFile));
String Lables = "\t" + "\t" + "\t" + "\t" + Arrays.toString(geneExpressionDataset.labels);
String Samples = "\t" + "\t" + "\t" + "\t" + Arrays.toString(geneExpressionDataset.sampleIds);
buf.write(Lables + "\r\n" + Samples + "\r\n");
for (int i = 0; i < geneExpressionDataset.genesNumber; i++){
buf.write(geneExpressionDataset.geneIds[i] + "\t"+ geneExpressionDataset.geneSymbols[i] + "\t" +
changeformat(geneExpressionDataset.dataMatrix[i]) + "\r\n");
}
buf.close();
}
/**
*
* writeTopDifferentiallyExpressedGenesToFile
*
* #param outputFilename
* #param geneExpressionDataset
* #param alpha
* #param label1
* #param label2
* #return numOfDiffGenes The number of differentially expressed genes detected, having p-value lower than alpha
* #throws IOException
*/
public static int writeTopDifferentiallyExpressedGenesToFile(String outputFilename,
GeneExpressionDataset geneExpressionDataset, double alpha,
String label1, String label2) throws IOException {
double pValues[] = new double[geneExpressionDataset.genesNumber];
int counter = 0;
for (int i = 0; i < pValues.length; i++){
double pval = calcTtest(geneExpressionDataset, i, label1, label2);
if (pval < alpha){
pValues[i] = pval;
counter++;
}
else{
continue;
}
}
File tofile = new File(outputFilename);
BufferedWriter buf = new BufferedWriter(new FileWriter(tofile));
int j = 0;
while (min(pValues) != -1){
String PVal = String.format("%.6f", pValues[min(pValues)]);
String gene_id = geneExpressionDataset.geneIds[min(pValues)];
String gene_symbol = geneExpressionDataset.geneSymbols[min(pValues)];
String line = String.valueOf(j) + "\t" + PVal + "\t" + gene_id + "\t" + gene_symbol;
buf.write(line + "\r\n");
pValues[min(pValues)] = 3.0;
j++;
}
buf.close();
return counter;
}
/**
*
* getDataEntriesForLabel
*
* Returns the entries in the 'data' array for which the corresponding entries in the 'labels' array equals 'label'
*
* #param data
* #param labels
* #param label
* #return
*/
public static double[] getDataEntriesForLabel(float[] data, String[] labels, String label) {
double[] array = new double[data.length];
int counter = 0;
for (int i = 0; i < data.length; i++){
if (labels[i].equals(label)){
array[counter] = data[i];
counter++;
}
else{
continue;
}
}return CutToCounter(array, counter);
}
/**
* calcTtest - returns a pValue for the t-Test
*
* Returns the p-value, associated with a two-sample, two-tailed t-test comparing the means of the input arrays
*
* //http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/stat/inference/TTest.html#tTest(double[], double[])
*
* #param geneExpressionDataset
* #param geneIndex
* #param label1
* #param label2
* #return
*/
private static double calcTtest(GeneExpressionDataset geneExpressionDataset, int geneIndex, String label1, String label2) {
double[] sample1 = getDataEntriesForLabel(geneExpressionDataset.dataMatrix[geneIndex], geneExpressionDataset.labels, label1);
double[] sample2 = getDataEntriesForLabel(geneExpressionDataset.dataMatrix[geneIndex], geneExpressionDataset.labels, label2);
return TestUtils.tTest(sample1, sample2);
}
/**
*
* GeneExpressionDataset
* A class representing a gene expression dataset
*
* #author software1-2014
*
*/
public static class GeneExpressionDataset {
public int samplesNumber; //number of dataset samples
public int genesNumber; // number of dataset gene probes
public String[] sampleIds; //sample ids
public String[] geneIds; //gene probe ids
public String[] geneSymbols; //gene symbols
public float[][] dataMatrix; //expression data matrix
public String[] labels; //sample labels
}
}
now, it won't compile and the error message is this:
"GeneExpressionAnalyzer.java:2: error: package org.apache.commons.math3.stat.inference does not exist
import org.apach.commons.math3.stat.interference.TestUtils;
GeneExpressionAnalyzer.java:277: error: cannot find symbol
return TestUtils.tTest;
symbol: variable TestUtils
location: class GeneExpressionAnalyzer
2 errors"
I don't get what went wrong, obviously i've added the .jar file that contains the path to TestUtils.
(here it is: http://apache.spd.co.il//commons/math/binaries/commons-math3-3.2-bin.zip)
any insights?
If you are working with eclipse,
Manually download the jar file from here
After that in eclipse open the package explorer -> right click on your project
Build Path -> Configure Build Path, A window will open.
Under the Libraries tab -> click Add External JARs. select the jar file you have downloaded Click Ok.
That's all. Now the problem might be gone
Does it work from the command line?
I've shortened your class to
import org.apache.commons.math3.stat.inference.TestUtils;
import java.io.*;
import java.util.Arrays;
public class Test {
public static void main(String args[]) throws IOException {
System.out.printf ("test...");
}
}
I copied the Test.java file and the commons-math3-3.2.jar to the same directory and here is my output from the command line:
C:\temp\test>dir
Répertoire de C:\temp\test
24/04/2014 14:41 <REP> .
24/04/2014 14:41 <REP> ..
24/04/2014 14:38 1 692 782 commons-math3-3.2.jar
24/04/2014 14:41 230 Test.java
2 fichier(s) 1 693 012 octets
2 Rép(s) 23 170 342 912 octets libres
C:\temp\test>javac Test.java
Test.java:1: package org.apache.commons.math3.stat.inference does not exist
import org.apache.commons.math3.stat.inference.TestUtils;
^
1 error
C:\temp\test>javac -cp commons-math3-3.2.jar Test.java
C:\temp\test>dir
Répertoire de C:\temp\test
24/04/2014 14:41 <REP> .
24/04/2014 14:41 <REP> ..
24/04/2014 14:38 1 692 782 commons-math3-3.2.jar
24/04/2014 14:41 500 Test.class
24/04/2014 14:41 230 Test.java

Reading a IDX file type in Java

I have built a image classifier in Java that I would like to test against the images provided here: http://yann.lecun.com/exdb/mnist/
Unfortunately, if you download the train-images-idx3-ubyte.gz or any of the other 3 files, they are all of file type: .idx1-ubyte
First Question:
I was wondering if anyone can give me instructions on how to make the .idx1-ubyte into bitmaps (.bmp) files?
Second Question:
Or just how I can read these files in general?
Information about the IDX file format:
the IDX file format is a simple format for vectors and multidimensional matrices of various numerical types.
The basic format is:
magic number
size in dimension 0
size in dimension 1
size in dimension 2
.....
size in dimension N
data
The magic number is an integer (MSB first). The first 2 bytes are always 0.
The third byte codes the type of the data:
0x08: unsigned byte
0x09: signed byte
0x0B: short (2 bytes)
0x0C: int (4 bytes)
0x0D: float (4 bytes)
0x0E: double (8 bytes)
The 4-th byte codes the number of dimensions of the vector/matrix: 1 for vectors, 2 for matrices....
The sizes in each dimension are 4-byte integers (MSB first, high endian, like in most non-Intel processors).
The data is stored like in a C array, i.e. the index in the last dimension changes the fastest.
Pretty Straightforward, as WPrecht said: "The URL describes the format you have to decode". This is my ImageSet exporter for the idx file, not very clean, but does what it has to do.
public class IdxReader {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileInputStream inImage = null;
FileInputStream inLabel = null;
String inputImagePath = "CBIR_Project/imagesRaw/MNIST/train-images-idx3-ubyte";
String inputLabelPath = "CBIR_Project/imagesRaw/MNIST/train-labels-idx1-ubyte";
String outputPath = "CBIR_Project/images/MNIST_Database_ARGB/";
int[] hashMap = new int[10];
try {
inImage = new FileInputStream(inputImagePath);
inLabel = new FileInputStream(inputLabelPath);
int magicNumberImages = (inImage.read() << 24) | (inImage.read() << 16) | (inImage.read() << 8) | (inImage.read());
int numberOfImages = (inImage.read() << 24) | (inImage.read() << 16) | (inImage.read() << 8) | (inImage.read());
int numberOfRows = (inImage.read() << 24) | (inImage.read() << 16) | (inImage.read() << 8) | (inImage.read());
int numberOfColumns = (inImage.read() << 24) | (inImage.read() << 16) | (inImage.read() << 8) | (inImage.read());
int magicNumberLabels = (inLabel.read() << 24) | (inLabel.read() << 16) | (inLabel.read() << 8) | (inLabel.read());
int numberOfLabels = (inLabel.read() << 24) | (inLabel.read() << 16) | (inLabel.read() << 8) | (inLabel.read());
BufferedImage image = new BufferedImage(numberOfColumns, numberOfRows, BufferedImage.TYPE_INT_ARGB);
int numberOfPixels = numberOfRows * numberOfColumns;
int[] imgPixels = new int[numberOfPixels];
for(int i = 0; i < numberOfImages; i++) {
if(i % 100 == 0) {System.out.println("Number of images extracted: " + i);}
for(int p = 0; p < numberOfPixels; p++) {
int gray = 255 - inImage.read();
imgPixels[p] = 0xFF000000 | (gray<<16) | (gray<<8) | gray;
}
image.setRGB(0, 0, numberOfColumns, numberOfRows, imgPixels, 0, numberOfColumns);
int label = inLabel.read();
hashMap[label]++;
File outputfile = new File(outputPath + label + "_0" + hashMap[label] + ".png");
ImageIO.write(image, "png", outputfile);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (inImage != null) {
try {
inImage.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (inLabel != null) {
try {
inLabel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
I created some classes for reading the MNIST handwritten digits data set with Java. The classes can read the files after they have been decompressed (unzipped) from the files that are available at the download site. Classes that allow reading the original (compressed) files are part of a small MnistReader project.
These following classes are standalone (meaning that they do not have dependencies to third-party libraries) and are essentially in the Public Domain - meaning that they can just be copied into own projects. (Attributions would be appreciated, but not required) :
The MnistDecompressedReader class:
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Objects;
import java.util.function.Consumer;
/**
* A class for reading the MNIST data set from the <b>decompressed</b>
* (unzipped) files that are published at
* <a href="http://yann.lecun.com/exdb/mnist/">
* http://yann.lecun.com/exdb/mnist/</a>.
*/
public class MnistDecompressedReader
{
/**
* Default constructor
*/
public MnistDecompressedReader()
{
// Default constructor
}
/**
* Read the MNIST training data from the given directory. The data is
* assumed to be located in files with their default names,
* <b>decompressed</b> from the original files:
* extension) :
* <code>train-images.idx3-ubyte</code> and
* <code>train-labels.idx1-ubyte</code>.
*
* #param inputDirectoryPath The input directory
* #param consumer The consumer that will receive the resulting
* {#link MnistEntry} instances
* #throws IOException If an IO error occurs
*/
public void readDecompressedTraining(Path inputDirectoryPath,
Consumer<? super MnistEntry> consumer) throws IOException
{
String trainImagesFileName = "train-images.idx3-ubyte";
String trainLabelsFileName = "train-labels.idx1-ubyte";
Path imagesFilePath = inputDirectoryPath.resolve(trainImagesFileName);
Path labelsFilePath = inputDirectoryPath.resolve(trainLabelsFileName);
readDecompressed(imagesFilePath, labelsFilePath, consumer);
}
/**
* Read the MNIST training data from the given directory. The data is
* assumed to be located in files with their default names,
* <b>decompressed</b> from the original files:
* extension) :
* <code>t10k-images.idx3-ubyte</code> and
* <code>t10k-labels.idx1-ubyte</code>.
*
* #param inputDirectoryPath The input directory
* #param consumer The consumer that will receive the resulting
* {#link MnistEntry} instances
* #throws IOException If an IO error occurs
*/
public void readDecompressedTesting(Path inputDirectoryPath,
Consumer<? super MnistEntry> consumer) throws IOException
{
String testImagesFileName = "t10k-images.idx3-ubyte";
String testLabelsFileName = "t10k-labels.idx1-ubyte";
Path imagesFilePath = inputDirectoryPath.resolve(testImagesFileName);
Path labelsFilePath = inputDirectoryPath.resolve(testLabelsFileName);
readDecompressed(imagesFilePath, labelsFilePath, consumer);
}
/**
* Read the MNIST data from the specified (decompressed) files.
*
* #param imagesFilePath The path of the images file
* #param labelsFilePath The path of the labels file
* #param consumer The consumer that will receive the resulting
* {#link MnistEntry} instances
* #throws IOException If an IO error occurs
*/
public void readDecompressed(Path imagesFilePath, Path labelsFilePath,
Consumer<? super MnistEntry> consumer) throws IOException
{
try (InputStream decompressedImagesInputStream =
new FileInputStream(imagesFilePath.toFile());
InputStream decompressedLabelsInputStream =
new FileInputStream(labelsFilePath.toFile()))
{
readDecompressed(
decompressedImagesInputStream,
decompressedLabelsInputStream,
consumer);
}
}
/**
* Read the MNIST data from the given (decompressed) input streams.
* The caller is responsible for closing the given streams.
*
* #param decompressedImagesInputStream The decompressed input stream
* containing the image data
* #param decompressedLabelsInputStream The decompressed input stream
* containing the label data
* #param consumer The consumer that will receive the resulting
* {#link MnistEntry} instances
* #throws IOException If an IO error occurs
*/
public void readDecompressed(
InputStream decompressedImagesInputStream,
InputStream decompressedLabelsInputStream,
Consumer<? super MnistEntry> consumer) throws IOException
{
Objects.requireNonNull(consumer, "The consumer may not be null");
DataInputStream imagesDataInputStream =
new DataInputStream(decompressedImagesInputStream);
DataInputStream labelsDataInputStream =
new DataInputStream(decompressedLabelsInputStream);
int magicImages = imagesDataInputStream.readInt();
if (magicImages != 0x803)
{
throw new IOException("Expected magic header of 0x803 "
+ "for images, but found " + magicImages);
}
int magicLabels = labelsDataInputStream.readInt();
if (magicLabels != 0x801)
{
throw new IOException("Expected magic header of 0x801 "
+ "for labels, but found " + magicLabels);
}
int numberOfImages = imagesDataInputStream.readInt();
int numberOfLabels = labelsDataInputStream.readInt();
if (numberOfImages != numberOfLabels)
{
throw new IOException("Found " + numberOfImages
+ " images but " + numberOfLabels + " labels");
}
int numRows = imagesDataInputStream.readInt();
int numCols = imagesDataInputStream.readInt();
for (int n = 0; n < numberOfImages; n++)
{
byte label = labelsDataInputStream.readByte();
byte imageData[] = new byte[numRows * numCols];
read(imagesDataInputStream, imageData);
MnistEntry mnistEntry = new MnistEntry(
n, label, numRows, numCols, imageData);
consumer.accept(mnistEntry);
}
}
/**
* Read bytes from the given input stream, filling the given array
*
* #param inputStream The input stream
* #param data The array to be filled
* #throws IOException If the input stream does not contain enough bytes
* to fill the array, or any other IO error occurs
*/
private static void read(InputStream inputStream, byte data[])
throws IOException
{
int offset = 0;
while (true)
{
int read = inputStream.read(
data, offset, data.length - offset);
if (read < 0)
{
break;
}
offset += read;
if (offset == data.length)
{
return;
}
}
throw new IOException("Tried to read " + data.length
+ " bytes, but only found " + offset);
}
}
The MnistEntry class:
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
/**
* An entry of the MNIST data set. Instances of this class will be passed
* to the consumer that is given to the {#link MnistCompressedReader} and
* {#link MnistDecompressedReader} reading methods.
*/
public class MnistEntry
{
/**
* The index of the entry
*/
private final int index;
/**
* The class label of the entry
*/
private final byte label;
/**
* The number of rows of the image data
*/
private final int numRows;
/**
* The number of columns of the image data
*/
private final int numCols;
/**
* The image data
*/
private final byte[] imageData;
/**
* Default constructor
*
* #param index The index
* #param label The label
* #param numRows The number of rows
* #param numCols The number of columns
* #param imageData The image data
*/
MnistEntry(int index, byte label, int numRows, int numCols,
byte[] imageData)
{
this.index = index;
this.label = label;
this.numRows = numRows;
this.numCols = numCols;
this.imageData = imageData;
}
/**
* Returns the index of the entry
*
* #return The index
*/
public int getIndex()
{
return index;
}
/**
* Returns the class label of the entry. This is a value in [0,9],
* indicating which digit is shown in the entry
*
* #return The class label
*/
public byte getLabel()
{
return label;
}
/**
* Returns the number of rows of the image data.
* This will usually be 28.
*
* #return The number of rows
*/
public int getNumRows()
{
return numRows;
}
/**
* Returns the number of columns of the image data.
* This will usually be 28.
*
* #return The number of columns
*/
public int getNumCols()
{
return numCols;
}
/**
* Returns a <i>reference</i> to the image data. This will be an array
* of length <code>numRows * numCols</code>, containing values
* in [0,255] indicating the brightness of the pixels.
*
* #return The image data
*/
public byte[] getImageData()
{
return imageData;
}
/**
* Creates a new buffered image from the image data that is stored
* in this entry.
*
* #return The image
*/
public BufferedImage createImage()
{
BufferedImage image = new BufferedImage(getNumCols(),
getNumRows(), BufferedImage.TYPE_BYTE_GRAY);
DataBuffer dataBuffer = image.getRaster().getDataBuffer();
DataBufferByte dataBufferByte = (DataBufferByte) dataBuffer;
byte data[] = dataBufferByte.getData();
System.arraycopy(getImageData(), 0, data, 0, data.length);
return image;
}
#Override
public String toString()
{
String indexString = String.format("%05d", index);
return "MnistEntry["
+ "index=" + indexString + ","
+ "label=" + label + "]";
}
}
The reader can be used to read the uncompressed files. The result will be MnistEntry instances that are passed to a consumer:
MnistDecompressedReader mnistReader = new MnistDecompressedReader();
mnistReader.readDecompressedTraining(Paths.get("./data"), mnistEntry ->
{
System.out.println("Read entry " + mnistEntry);
BufferedImage image = mnistEntry.createImage();
...
});
The MnistReader project contains several examples of how these classes may be used to read the compressed- or uncompressed data, or to generate PNG images from the MNIST entries.
The URL describes the format you have to decode, and they mention it's non-standard, so the obvious Google search doesn't turn up any code of use. However, it's very straight forward with a header followed by a 28x28 pixel matrix of 0-255 gray scale values.
Once you have the data read out (remember to pay attention to endian-ness), creating BMP files is straight forward.
I recommend the following article to you:
How to make bmp image from pixel byte array in java
their question is about color, but their code already works for gray scale and that's what you need anyway, you should be able to get something going from that snippet.

Embed files into Excel using Apache POI

I am exporting data to Excel file using Apache POI. In one weird requirement, I need to embed one file in the Excel using this POI. I have the file, and can be taken into streams or as byte arrays. After googling for much time, I am in a doubt whether POI really supports my requirement. Can we embed files into Excel? :-(
Cheers,
Anoop
Ok, this took very long to finally work out, as there were a few things which didn't look very important at the beginning, but actually corrupted the file when they haven't been set right - especially in the Ole10Native wrapper, part of the unknown2 field actually contained the size (in bytes) of the following command string.
But first things first:
When you want to embed arbitrary files into one of the office formats, your best bet is to use the OLE 1.0 packager. It will be typically used, when you select insert->object from file.
So I've re-engineered an Excel 2003 file containing a PPT. As mentioned in my comment above, Excel will store its embedded objects in DirectoryNodes named "MBD....". In case of a Ole 1.0 Packager object, the interesting data will be found in the \1Ole10Native entry.
When you've inserted the data, you'll need to link it somehow in the Excel sheet. This is done by an EscherObject similar to a picture entry with additional attached records.
Apart from the many undocumented flags, there were a few things which puzzled me:
are the storage ids for the embedded objects just randomly assigned or is there some kind of number system?
I've searched for a more detailed description of the Ole10Native wrapper and especially for the ole 1.0 packager format, but apart of the M$ docu which sketchily handles it as one big byte chunk, most sources did some reengineering which looked very similar to the poi Ole10Native class ... of course the idea to check the libre office source came also to mind, but I have to admit the ones I've checked, only confused me :(
which one is the right clsid for the embedded object? ... i.e. for powerpoint there are quite a few. So if in doubt, obviously you'll need to lookup the clsid by a previously saved file from Office
Excel 2010 generates Biff8 files which embedded objects can't be opened by Libre Office!?!
the ole10Native object contains among other things a command line entry. would be interesting if someone can start other things than the embedded object with it ...
the BiffViewer crashed when I've used preview images bigger than some chunk size (~6kb). So either images would need to be chunked or the BiffViewer implementation is wrong ... this also caused some confusing for a while ...
Tested with POI 3.9, Libre Office 4.0, Office 2010 (I don't have Office 2003 anymore ...)
import java.awt.Color;
import java.io.*;
import java.lang.reflect.*;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.filechooser.FileSystemView;
import org.apache.poi.ddf.*;
import org.apache.poi.hpsf.ClassID;
import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.model.*;
import org.apache.poi.hslf.model.ShapeTypes;
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.hssf.dev.BiffViewer;
import org.apache.poi.hssf.model.*;
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.util.*;
#SuppressWarnings("unused")
public class PoiOlePptInXls {
public static final OleType PACKAGE = new OleType("{0003000C-0000-0000-C000-000000000046}");
public static final OleType PPT_SHOW = new OleType("{64818D10-4F9B-11CF-86EA-00AA00B929E8}");
public static final OleType XLS_WORKBOOK = new OleType("{00020841-0000-0000-C000-000000000046}");
public static final OleType TXT_ONLY = new OleType("{5e941d80-bf96-11cd-b579-08002b30bfeb}"); // ???
static class OleType {
final String classId;
OleType(String classId) {
this.classId = classId;
}
ClassID getClassID() {
ClassID cls = new ClassID();
byte clsBytes[] = cls.getBytes();
String clsStr = classId.replaceAll("[{}-]", "");
for (int i=0; i<clsStr.length(); i+=2) {
clsBytes[i/2] = (byte)Integer.parseInt(clsStr.substring(i, i+2), 16);
}
return cls;
}
}
public static void main(String[] args) throws Exception {
POIFSFileSystem poifs = new POIFSFileSystem();
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
int previewIdxPpt = generatePreview(wb, "application/powerpoint");
int storageIdPpt = packageOleData(poifs, getSamplePPT(), "Example.ppt", "Example.ppt", "Example.ppt");
int previewIdxXls = generatePreview(wb, "application/excel");
int storageIdXls = packageOleData(poifs, getSampleXLS(), "Example.xls", "Example.xls", "Example.xls");
int previewIdxTxt = generatePreview(wb, "text/plain");
int storageIdTxt = packageOleData(poifs, getSampleTXT(), "Example.txt", "Example.txt", "Example.txt");
int rowoffset = 5;
int coloffset = 5;
CreationHelper ch = wb.getCreationHelper();
HSSFClientAnchor anchor = (HSSFClientAnchor)ch.createClientAnchor();
anchor.setAnchor((short)(2+coloffset), 1+rowoffset, 0, 0, (short)(3+coloffset), 5+rowoffset, 0, 0);
anchor.setAnchorType(ClientAnchor.DONT_MOVE_AND_RESIZE);
HSSFObjectData oleShape = createObjectData(poifs, storageIdPpt, 1, anchor, previewIdxPpt);
addShape(patriarch, oleShape);
anchor = (HSSFClientAnchor)ch.createClientAnchor();
anchor.setAnchor((short)(5+coloffset), 1+rowoffset, 0, 0, (short)(6+coloffset), 5+rowoffset, 0, 0);
anchor.setAnchorType(ClientAnchor.DONT_MOVE_AND_RESIZE);
oleShape = createObjectData(poifs, storageIdXls, 2, anchor, previewIdxXls);
addShape(patriarch, oleShape);
anchor = (HSSFClientAnchor)ch.createClientAnchor();
anchor.setAnchor((short)(3+coloffset), 10+rowoffset, 0, 0, (short)(5+coloffset), 11+rowoffset, 0, 0);
anchor.setAnchorType(ClientAnchor.DONT_MOVE_AND_RESIZE);
oleShape = createObjectData(poifs, storageIdTxt, 3, anchor, previewIdxTxt);
addShape(patriarch, oleShape);
anchor = (HSSFClientAnchor)ch.createClientAnchor();
anchor.setAnchor((short)(1+coloffset), -2+rowoffset, 0, 0, (short)(7+coloffset), 14+rowoffset, 0, 0);
anchor.setAnchorType(ClientAnchor.DONT_MOVE_AND_RESIZE);
HSSFSimpleShape circle = patriarch.createSimpleShape(anchor);
circle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);
circle.setNoFill(true);
poifs.getRoot().createDocument("Workbook", new ByteArrayInputStream(wb.getBytes()));
FileOutputStream fos = new FileOutputStream("ole_ppt_in_xls.xls");
poifs.writeFilesystem(fos);
fos.close();
}
static void addShape(HSSFPatriarch patriarch, HSSFShape shape) throws Exception {
patriarch.addShape(shape);
Method m = HSSFPatriarch.class.getDeclaredMethod("onCreate", HSSFShape.class);
m.setAccessible(true);
m.invoke(patriarch, shape);
}
static HSSFObjectData createObjectData(POIFSFileSystem poifs, int storageId, int objectIdx, HSSFClientAnchor anchor, int previewIdx) {
ObjRecord obj = new ObjRecord();
CommonObjectDataSubRecord ftCmo = new CommonObjectDataSubRecord();
ftCmo.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_PICTURE);
ftCmo.setObjectId(objectIdx);
ftCmo.setLocked(true);
ftCmo.setPrintable(true);
ftCmo.setAutofill(true);
ftCmo.setAutoline(true);
ftCmo.setReserved1(0);
ftCmo.setReserved2(0);
ftCmo.setReserved3(0);
obj.addSubRecord(ftCmo);
obj.addSubRecord(SubRecord.createSubRecord(new LittleEndianByteArrayInputStream(new byte[]{7,0,2,0,2,0}), 0));
obj.addSubRecord(SubRecord.createSubRecord(new LittleEndianByteArrayInputStream(new byte[]{8,0,2,0,1,0}), 0));
EmbeddedObjectRefSubRecord ftPictFmla;
try {
Constructor<EmbeddedObjectRefSubRecord> con = EmbeddedObjectRefSubRecord.class.getDeclaredConstructor();
con.setAccessible(true);
ftPictFmla = con.newInstance();
} catch (Exception e) {
throw new RuntimeException("oops", e);
}
setField(ftPictFmla, "field_2_unknownFormulaData", new byte[]{2, 0, 0, 0, 0});
setField(ftPictFmla, "field_4_ole_classname", "Paket");
setField(ftPictFmla, "field_5_stream_id", (Integer)storageId);
obj.addSubRecord(ftPictFmla);
obj.addSubRecord(new EndSubRecord());
// create temporary picture, but don't attach it.
// It's neccessary to create the sp-container, which need to be minimal modified
// for oleshapes
HSSFPicture shape = new HSSFPicture(null, anchor);
EscherContainerRecord spContainer;
try {
Method m = HSSFPicture.class.getDeclaredMethod("createSpContainer");
m.setAccessible(true);
spContainer = (EscherContainerRecord)m.invoke(shape);
} catch (Exception e) {
throw new RuntimeException("oops", e);
}
EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);
spRecord.setFlags(spRecord.getFlags() | EscherSpRecord.FLAG_OLESHAPE);
spRecord.setShapeType((byte)0x4B);
EscherOptRecord optRecord = spContainer.getChildById(EscherOptRecord.RECORD_ID);
EscherProperty ep = new EscherSimpleProperty(EscherProperties.BLIP__PICTUREID, false, false, 1);
optRecord.addEscherProperty(ep);
DirectoryEntry oleRoot;
try {
oleRoot = (DirectoryEntry)poifs.getRoot().getEntry(formatStorageId(storageId));
} catch (FileNotFoundException e) {
throw new RuntimeException("oops", e);
}
HSSFObjectData oleShape = new HSSFObjectData(spContainer, obj, oleRoot);
oleShape.setPictureIndex(previewIdx);
return oleShape;
}
static void setField(Object clazz, String fieldname, Object value) {
try {
Field f = clazz.getClass().getDeclaredField(fieldname);
f.setAccessible(true);
f.set(clazz, value);
} catch (Exception e) {
throw new RuntimeException("oops", e);
}
}
static void addOleStreamEntry(DirectoryEntry dir) throws IOException {
final String OLESTREAM_NAME = "\u0001Ole";
if (!dir.hasEntry(OLESTREAM_NAME)) {
// the following data was taken from an example libre office document
// beside this "\u0001Ole" record there were several other records, e.g. CompObj,
// OlePresXXX, but it seems, that they aren't neccessary
byte oleBytes[] = { 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
dir.createDocument(OLESTREAM_NAME, new ByteArrayInputStream(oleBytes));
}
}
static String formatStorageId(int storageId) {
return String.format("MBD%1$08X", storageId);
}
static int packageOleData(POIFSFileSystem poifs, byte oleData[], String label, String fileName, String command) throws IOException {
DirectoryNode root = poifs.getRoot();
// get free MBD-Node
int storageId = 0;
DirectoryEntry oleDir = null;
do {
String storageStr = formatStorageId(++storageId);
if (!root.hasEntry(storageStr)) {
oleDir = root.createDirectory(storageStr);
oleDir.setStorageClsid(PACKAGE.getClassID());
}
} while (oleDir == null);
addOleStreamEntry(oleDir);
Ole10Native2 oleNative = new Ole10Native2();
oleNative.setLabel(label);
oleNative.setFileName(fileName);
oleNative.setCommand(command);
oleNative.setDataBuffer(oleData);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
oleNative.writeOut(bos);
byte buf1[] = bos.toByteArray();
oleDir.createDocument(Ole10Native2.OLE10_NATIVE, new ByteArrayInputStream(buf1));
return storageId;
}
static byte[] getSamplePPT() {
HSLFSlideShow ss = HSLFSlideShow.create();
SlideShow ppt = new SlideShow(ss);
Slide slide = ppt.createSlide();
AutoShape sh1 = new AutoShape(ShapeTypes.Star32);
sh1.setAnchor(new java.awt.Rectangle(50, 50, 100, 200));
sh1.setFillColor(Color.red);
slide.addShape(sh1);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ppt.write(bos);
POIFSFileSystem poifs = new POIFSFileSystem(new ByteArrayInputStream(bos.toByteArray()));
poifs.getRoot().setStorageClsid(PPT_SHOW.getClassID());
bos.reset();
poifs.writeFilesystem(bos);
return bos.toByteArray();
} catch (IOException e) {
throw new RuntimeException("bla", e);
}
}
static byte[] getSampleXLS() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
sheet.createRow(5).createCell(2).setCellValue("yo dawg i herd you like embeddet objekts, so we put a ole in your ole so you can save a file while you save a file");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
wb.write(bos);
POIFSFileSystem poifs = new POIFSFileSystem(new ByteArrayInputStream(bos.toByteArray()));
poifs.getRoot().setStorageClsid(XLS_WORKBOOK.getClassID());
bos.reset();
poifs.writeFilesystem(bos);
return bos.toByteArray();
} catch (IOException e) {
throw new RuntimeException("bla", e);
}
}
static byte[] getSampleTXT() {
return "All your base are belong to us".getBytes();
}
/**
* to be defined, how to create a preview image for a start, I've taken just
* a dummy image, which will be replaced, when the user activates the ole
* object
*
* not really an alternativ:
* http://stackoverflow.com/questions/16704624/how-
* to-print-a-workbook-file-made-using-apache-poi-and-java
*
* #return image index of the preview image
*/
static int generatePreview(HSSFWorkbook workbook, String mimetype) {
try {
String url = "";
if ("application/powerpoint".equals(mimetype)) {
url = "http://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/LibreOffice_Impress_icon_3.3.1_48_px.svg/40px-LibreOffice_Impress_icon_3.3.1_48_px.svg.png";
} else if ("application/excel".equals(mimetype)) {
url = "http://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/LibreOffice_Calc_icon_3.3.1_48_px.svg/40px-LibreOffice_Calc_icon_3.3.1_48_px.svg.png";
} else if ("text/plain".equals(mimetype)) {
url = "http://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/LibreOffice_Writer_icon_3.3.1_48_px.svg/40px-LibreOffice_Writer_icon_3.3.1_48_px.svg.png";
}
InputStream is = new URL(url).openStream();
byte previewImg[] = IOUtils.toByteArray(is);
is.close();
int pictIdx = workbook.addPicture(previewImg, HSSFWorkbook.PICTURE_TYPE_PNG);
return pictIdx;
} catch (IOException e) {
throw new RuntimeException("not really?", e);
}
}
/*
* Helper - determine length of zero terminated string (ASCIIZ).
*/
private static int getStringLength(byte[] data, int ofs) {
int len = 0;
while (len + ofs < data.length && data[ofs + len] != 0) {
len++;
}
len++;
return len;
}
}
The adapted Ole10Native class of POI with write-support:
import java.io.*;
import org.apache.poi.poifs.filesystem.*;
import org.apache.poi.util.*;
/**
* Represents an Ole10Native record which is wrapped around certain binary files
* being embedded in OLE2 documents.
*
* #author Rainer Schwarze
*/
public class Ole10Native2 {
public static final String OLE10_NATIVE = "\u0001Ole10Native";
protected static final String ISO1 = "ISO-8859-1";
// (the fields as they appear in the raw record:)
protected int totalSize; // 4 bytes, total size of record not including this
// field
protected short flags1 = 2; // 2 bytes, unknown, mostly [02 00]
protected String label; // ASCIIZ, stored in this field without the
// terminating zero
protected String fileName; // ASCIIZ, stored in this field without the
// terminating zero
protected short flags2 = 0; // 2 bytes, unknown, mostly [00 00]
protected short unknown1 = 3;
protected String command; // ASCIIZ, stored in this field without the
// terminating zero
protected byte[] dataBuffer; // varying size, the actual native data
protected short flags3 = 0; // some final flags? or zero terminators?,
// sometimes not there
/**
* Creates an instance of this class from an embedded OLE Object. The OLE
* Object is expected to include a stream "{01}Ole10Native" which
* contains the actual data relevant for this class.
*
* #param poifs
* POI Filesystem object
* #return Returns an instance of this class
* #throws IOException
* on IO error
* #throws Ole10NativeException
* on invalid or unexcepted data format
*/
public static Ole10Native2 createFromEmbeddedOleObject(POIFSFileSystem poifs) throws IOException, Ole10NativeException {
return createFromEmbeddedOleObject(poifs.getRoot());
}
/**
* Creates an instance of this class from an embedded OLE Object. The OLE
* Object is expected to include a stream "{01}Ole10Native" which
* contains the actual data relevant for this class.
*
* #param directory
* POI Filesystem object
* #return Returns an instance of this class
* #throws IOException
* on IO error
* #throws Ole10NativeException
* on invalid or unexcepted data format
*/
public static Ole10Native2 createFromEmbeddedOleObject(DirectoryNode directory) throws IOException, Ole10NativeException {
boolean plain = false;
try {
directory.getEntry("\u0001Ole10ItemName");
plain = true;
} catch (FileNotFoundException ex) {
plain = false;
}
DocumentEntry nativeEntry = (DocumentEntry) directory.getEntry(OLE10_NATIVE);
byte[] data = new byte[nativeEntry.getSize()];
directory.createDocumentInputStream(nativeEntry).read(data);
return new Ole10Native2(data, 0, plain);
}
/**
* Creates an instance and fills the fields based on the data in the given
* buffer.
*
* #param data
* The buffer containing the Ole10Native record
* #param offset
* The start offset of the record in the buffer
* #throws Ole10NativeException
* on invalid or unexcepted data format
*/
public Ole10Native2(byte[] data, int offset) throws Ole10NativeException {
this(data, offset, false);
}
/**
* Creates an instance and fills the fields based on the data in the given
* buffer.
*
* #param data
* The buffer containing the Ole10Native record
* #param offset
* The start offset of the record in the buffer
* #param plain
* Specified 'plain' format without filename
* #throws Ole10NativeException
* on invalid or unexcepted data format
*/
public Ole10Native2(byte[] data, int offset, boolean plain) throws Ole10NativeException {
int ofs = offset; // current offset, initialized to start
if (data.length < offset + 2) {
throw new Ole10NativeException("data is too small");
}
totalSize = LittleEndian.getInt(data, ofs);
ofs += LittleEndianConsts.INT_SIZE;
if (plain) {
dataBuffer = new byte[totalSize - 4];
System.arraycopy(data, 4, dataBuffer, 0, dataBuffer.length);
int dataSize = totalSize - 4;
byte[] oleLabel = new byte[8];
System.arraycopy(dataBuffer, 0, oleLabel, 0, Math.min(dataBuffer.length, 8));
label = "ole-" + HexDump.toHex(oleLabel);
fileName = label;
command = label;
} else {
flags1 = LittleEndian.getShort(data, ofs);
ofs += LittleEndianConsts.SHORT_SIZE;
int len = getStringLength(data, ofs);
label = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
ofs += len;
len = getStringLength(data, ofs);
fileName = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
ofs += len;
flags2 = LittleEndian.getShort(data, ofs);
ofs += LittleEndianConsts.SHORT_SIZE;
unknown1 = LittleEndian.getShort(data, ofs);
ofs += LittleEndianConsts.SHORT_SIZE;
len = LittleEndian.getInt(data, ofs);
ofs += LittleEndianConsts.INT_SIZE;
command = StringUtil.getFromCompressedUnicode(data, ofs, len - 1);
ofs += len;
if (totalSize < ofs) {
throw new Ole10NativeException("Invalid Ole10Native");
}
int dataSize = LittleEndian.getInt(data, ofs);
ofs += LittleEndianConsts.INT_SIZE;
if (dataSize < 0 || totalSize - (ofs - LittleEndianConsts.INT_SIZE) < dataSize) {
throw new Ole10NativeException("Invalid Ole10Native");
}
dataBuffer = new byte[dataSize];
System.arraycopy(data, ofs, dataBuffer, 0, dataSize);
ofs += dataSize;
// if (unknown1.length > 0) {
// flags3 = LittleEndian.getShort(data, ofs);
// ofs += LittleEndianConsts.SHORT_SIZE;
// } else {
// flags3 = 0;
// }
}
}
public Ole10Native2() {}
/*
* Helper - determine length of zero terminated string (ASCIIZ).
*/
private static int getStringLength(byte[] data, int ofs) {
int len = 0;
while (len + ofs < data.length && data[ofs + len] != 0) {
len++;
}
len++;
return len;
}
/**
* Returns the value of the totalSize field - the total length of the
* structure is totalSize + 4 (value of this field + size of this field).
*
* #return the totalSize
*/
public int getTotalSize() {
return totalSize;
}
/**
* Returns flags1 - currently unknown - usually 0x0002.
*
* #return the flags1
*/
public short getFlags1() {
return flags1;
}
/**
* Returns the label field - usually the name of the file (without
* directory) but probably may be any name specified during
* packaging/embedding the data.
*
* #return the label
*/
public String getLabel() {
return label;
}
/**
* Returns the fileName field - usually the name of the file being embedded
* including the full path.
*
* #return the fileName
*/
public String getFileName() {
return fileName;
}
/**
* Returns flags2 - currently unknown - mostly 0x0000.
*
* #return the flags2
*/
public short getFlags2() {
return flags2;
}
/**
* Returns unknown1 field - currently unknown.
*
* #return the unknown1
*/
public short getUnknown1() {
return unknown1;
}
/**
* Returns the unknown2 field - currently being a byte[3] - mostly {0, 0,
* 0}.
*
* #return the unknown2
*/
// public short getUnknown2() {
// return unknown2;
// }
/**
* Returns the command field - usually the name of the file being embedded
* including the full path, may be a command specified during embedding the
* file.
*
* #return the command
*/
public String getCommand() {
return command;
}
/**
* Returns the size of the embedded file. If the size is 0 (zero), no data
* has been embedded. To be sure, that no data has been embedded, check
* whether {#link #getDataBuffer()} returns <code>null</code>.
*
* #return the dataSize
*/
public int getDataSize() {
return dataBuffer.length;
}
/**
* Returns the buffer containing the embedded file's data, or
* <code>null</code> if no data was embedded. Note that an embedding may
* provide information about the data, but the actual data is not included.
* (So label, filename etc. are available, but this method returns
* <code>null</code>.)
*
* #return the dataBuffer
*/
public byte[] getDataBuffer() {
return dataBuffer;
}
/**
* Returns the flags3 - currently unknown.
*
* #return the flags3
*/
public short getFlags3() {
return flags3;
}
/**
* Have the contents printer out into an OutputStream, used when writing a
* file back out to disk (Normally, atom classes will keep their bytes
* around, but non atom classes will just request the bytes from their
* children, then chuck on their header and return)
*/
public void writeOut(OutputStream out) throws IOException {
byte intbuf[] = new byte[LittleEndianConsts.INT_SIZE];
byte shortbuf[] = new byte[LittleEndianConsts.SHORT_SIZE];
byte bytebuf[] = new byte[LittleEndianConsts.BYTE_SIZE];
// LittleEndian.putInt(_header, 4, _data.length);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(intbuf); // total size, will be determined later ..
LittleEndian.putShort(shortbuf, 0, getFlags1());
bos.write(shortbuf);
bos.write(getLabel().getBytes(ISO1));
bos.write(0);
bos.write(getFileName().getBytes(ISO1));
bos.write(0);
LittleEndian.putShort(shortbuf, 0, getFlags2());
bos.write(shortbuf);
LittleEndian.putShort(shortbuf, 0, getUnknown1());
bos.write(shortbuf);
LittleEndian.putInt(intbuf, 0, getCommand().length()+1);
bos.write(intbuf);
bos.write(getCommand().getBytes(ISO1));
bos.write(0);
LittleEndian.putInt(intbuf, 0, getDataBuffer().length);
bos.write(intbuf);
bos.write(getDataBuffer());
LittleEndian.putShort(shortbuf, 0, getFlags3());
bos.write(shortbuf);
// update total size - length of length-field (4 bytes)
byte data[] = bos.toByteArray();
totalSize = data.length - LittleEndianConsts.INT_SIZE;
LittleEndian.putInt(data, 0, totalSize);
out.write(data);
}
public void setFlags1(short flags1) {
this.flags1 = flags1;
}
public void setFlags2(short flags2) {
this.flags2 = flags2;
}
public void setFlags3(short flags3) {
this.flags3 = flags3;
}
public void setLabel(String label) {
this.label = label;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public void setCommand(String command) {
this.command = command;
}
public void setUnknown1(short unknown1) {
this.unknown1 = unknown1;
}
// public void setUnknown2(short unknown2) {
// this.unknown2 = unknown2;
// }
public void setDataBuffer(byte dataBuffer[]) {
this.dataBuffer = dataBuffer;
}
}
This page of the online documentation might answer your question:
http://poi.apache.org/components/poifs/embeded.html

Categories