git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@517 52acb1d6-8a22-11de-b505-999d5b087335
407 lines
16 KiB
C#
407 lines
16 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices; // For DllImport()
|
|
|
|
public struct jas_matrix_t
|
|
{
|
|
/* A matrix of pixels (one matrix per component) */
|
|
public int flags; /* Additional state information. */
|
|
public int xstart; /* The starting horizontal index. */
|
|
public int ystart; /* The starting vertical index. */
|
|
public int xend; /* The ending horizontal index. */
|
|
public int yend; /* The ending vertical index. */
|
|
public int numrows; /* The number of rows in the matrix. */
|
|
public int numcols; /* The number of columns in the matrix. */
|
|
public IntPtr row_ptrs; /* Pointers to the start of each row. */
|
|
public int maxrows; /* The allocated size of the rows array. */
|
|
public IntPtr data; /* The matrix data buffer. */
|
|
public int datasize; /* The allocated size of the data array. */
|
|
|
|
public static jas_matrix_t fromPtr(IntPtr ptr)
|
|
{
|
|
return (jas_matrix_t)Marshal.PtrToStructure(ptr, typeof(jas_matrix_t));
|
|
}
|
|
|
|
public int[] get_int_array()
|
|
{
|
|
int[] retval = new int[datasize];
|
|
Marshal.Copy(data, retval, 0, datasize); /* only the low byte has any meaning */
|
|
return retval;
|
|
}
|
|
|
|
public int get_pixel(int x, int y)
|
|
{
|
|
return Marshal.ReadInt32(data, y * numcols + x);
|
|
}
|
|
}
|
|
|
|
public struct jas_image_cmpt_t
|
|
{ /* Image component class. */
|
|
public int tlx; /* The x-coordinate of the top-left corner of the component. */
|
|
public int tly; /* The y-coordinate of the top-left corner of the component. */
|
|
public int hstep; /* The horizontal sampling period in units of the reference grid. */
|
|
public int vstep; /* The vertical sampling period in units of the reference grid. */
|
|
public int width; /* The component width in samples. */
|
|
public int height; /* The component height in samples. */
|
|
public int prec; /* precision */
|
|
public int sgnd; /* signed-ness */
|
|
public IntPtr stream; /* The stream containing the component data. */
|
|
public int cps; /* The number of characters per sample in the stream. */
|
|
public int type; /* The type of component (e.g., opacity, red, green, blue, luma). */
|
|
|
|
public static jas_image_cmpt_t fromPtr(IntPtr ptr)
|
|
{
|
|
return (jas_image_cmpt_t)Marshal.PtrToStructure(ptr, typeof(jas_image_cmpt_t));
|
|
}
|
|
}
|
|
|
|
public struct jas_image_t
|
|
{
|
|
public int tlx; /* The x-coordinate of the top-left corner of the image bounding box. */
|
|
public int tly; /* The y-coordinate of the top-left corner of the image bounding box. */
|
|
public int brx; /* The x-coordinate of the bottom-right corner of the image bounding
|
|
box (plus one). */
|
|
public int bry; /* The y-coordinate of the bottom-right corner of the image bounding
|
|
box (plus one). */
|
|
public int numcmpts; /* The number of components. */
|
|
public int maxcmpts; /* The maximum number of components that this image can have (i.e., the
|
|
allocated size of the components array). */
|
|
public IntPtr cmpts; /* array of pointers to jas_image_cmpt_t: Per-component information. */
|
|
public int clrspc;
|
|
public IntPtr cmprof;
|
|
public bool inmem;
|
|
|
|
public static jas_image_t fromPtr(IntPtr ptr)
|
|
{
|
|
return (jas_image_t)Marshal.PtrToStructure(ptr, typeof(jas_image_t));
|
|
}
|
|
|
|
public int width { get { return brx - tlx; } }
|
|
public int height { get { return bry - tly; } }
|
|
|
|
public jas_image_cmpt_t[] get_components()
|
|
{
|
|
jas_image_cmpt_t[] retval = new jas_image_cmpt_t[numcmpts];
|
|
int i;
|
|
|
|
for (i = 0; i < numcmpts; i++) retval[i] = jas_image_cmpt_t.fromPtr(Marshal.ReadIntPtr(cmpts, i * 4));
|
|
return retval;
|
|
}
|
|
|
|
}
|
|
|
|
public class JasperWrapper
|
|
{
|
|
const string JASPER_LIBRARY = "libjasper.dll";
|
|
|
|
protected static bool Initialized = false;
|
|
protected static int Initialized_Value;
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
protected static extern int jas_init();
|
|
|
|
public static void jasper_init()
|
|
{
|
|
if (!Initialized)
|
|
{
|
|
Initialized = true;
|
|
jas_init(); // always returns zero.
|
|
}
|
|
}
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
private static extern IntPtr jas_getversion();
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
private static extern int jas_setdbglevel(int level);
|
|
|
|
[DllImport(JASPER_LIBRARY, CharSet=CharSet.Ansi)]
|
|
public static extern IntPtr jas_stream_fopen(string filename, string mode);
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
private static extern IntPtr jas_stream_memopen(IntPtr buf, int bufsize);
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
private static extern IntPtr jas_stream_tmpfile();
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
private static extern int jas_stream_rewind(IntPtr stream);
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
private static extern int jas_stream_copy(IntPtr out_stream, IntPtr in_stream, int all);
|
|
|
|
public static IntPtr jas_stream_memopen(byte[] buf)
|
|
{
|
|
IntPtr bufPtr = Marshal.AllocHGlobal(buf.Length);
|
|
Marshal.Copy(buf, 0, bufPtr, buf.Length);
|
|
|
|
return jas_stream_memopen(bufPtr, buf.Length);
|
|
}
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
public static extern int jas_stream_flush(IntPtr stream);
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
public static extern int jas_stream_close(IntPtr stream);
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
public static extern int jas_image_getfmt(IntPtr stream);
|
|
|
|
/* Get the ID for the image format with the specified name. */
|
|
[DllImport(JASPER_LIBRARY, CharSet=CharSet.Ansi)]
|
|
private static extern int jas_image_strtofmt(string name);
|
|
|
|
[DllImport(JASPER_LIBRARY, CharSet=CharSet.Ansi)]
|
|
public static extern int jas_image_fmtfromname(string filename);
|
|
|
|
[DllImport(JASPER_LIBRARY, CharSet=CharSet.Ansi)]
|
|
public static extern int jas_image_encode(IntPtr image, IntPtr out_stream, int fmt, string optstr);
|
|
|
|
[DllImport(JASPER_LIBRARY, CharSet=CharSet.Ansi)]
|
|
public static extern IntPtr jas_image_decode(IntPtr in_stream, int fmt, string optstr);
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
public static extern IntPtr jas_image_destroy(IntPtr image_ptr);
|
|
|
|
public static int jas_image_cmpttype(jas_image_t image, int cmptno)
|
|
{
|
|
jas_image_cmpt_t cmpt =
|
|
(jas_image_cmpt_t)Marshal.PtrToStructure(Marshal.ReadIntPtr(image.cmpts, cmptno * 4),
|
|
typeof(jas_image_cmpt_t));
|
|
return cmpt.type;
|
|
}
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
public static extern int jas_image_readcmpt(IntPtr image_ptr, int cmptno,
|
|
int x, int y, int width, int height, IntPtr data);
|
|
|
|
public static string get_jasper_version()
|
|
{
|
|
string text = Marshal.PtrToStringAnsi(jas_getversion());
|
|
if (text == null) throw new Exception("jas_getversion returned NULL\n");
|
|
return text;
|
|
}
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
public static extern IntPtr jas_matrix_create(int width, int height);
|
|
|
|
[DllImport(JASPER_LIBRARY)]
|
|
public static extern void jas_matrix_destroy(IntPtr matrix);
|
|
|
|
public static int[] get_multiplexed_image_data(IntPtr image_ptr, int[] order)
|
|
{
|
|
if (order.Length > 4) throw new Exception("order.Length must be <= 4");
|
|
jas_image_t image_struct = jas_image_t.fromPtr(image_ptr);
|
|
|
|
IntPtr matrix = jas_matrix_create(image_struct.height, image_struct.width);
|
|
int[] pixels = new int[image_struct.height * image_struct.width];
|
|
|
|
for (int c = 0; c < order.Length; c++)
|
|
{
|
|
if (order[c] == -1) for (int i = 0; i < pixels.Length; i++) pixels[i] |= 0xFF << (c * 8);
|
|
else
|
|
{
|
|
int retval = jas_image_readcmpt(image_ptr, order[c], 0, 0,
|
|
image_struct.width, image_struct.height, matrix);
|
|
if (retval != 0)
|
|
{
|
|
jas_matrix_destroy(matrix);
|
|
throw new Exception("jas_image_readcmpt returned " + retval);
|
|
}
|
|
|
|
int[] temp_array = (jas_matrix_t.fromPtr(matrix)).get_int_array();
|
|
for (int i = 0; i < temp_array.Length; i++) pixels[i] |= (temp_array[i] & 0xFF) << (c * 8);
|
|
}
|
|
}
|
|
jas_matrix_destroy(matrix);
|
|
return pixels;
|
|
}
|
|
|
|
public static String version
|
|
{
|
|
get { return get_jasper_version(); }
|
|
}
|
|
|
|
/* This function can convert any file format that GeoJASPER can read
|
|
(tif, jpg, bmp, pnm, ras) into j2c. The input format is determined
|
|
by the extension of the input file. */
|
|
|
|
public static byte[] jasper_encode_j2c(string filename) {
|
|
jasper_init();
|
|
IntPtr input_stream_ptr = jas_stream_fopen(filename, "rb");
|
|
int format = jas_image_getfmt(input_stream_ptr);
|
|
|
|
Console.WriteLine("file is format # " + format);
|
|
|
|
IntPtr image_ptr = jas_image_decode(input_stream_ptr, format, "");
|
|
if (image_ptr == IntPtr.Zero) throw new Exception("Error decoding image");
|
|
jas_image_t image_struct = jas_image_t.fromPtr(image_ptr);
|
|
|
|
int output_buffer_size = image_struct.width * image_struct.height *
|
|
image_struct.numcmpts * 4 + 4096; // it's called a safety margin
|
|
|
|
IntPtr bufPtr = Marshal.AllocHGlobal(output_buffer_size);
|
|
IntPtr output_stream_ptr = jas_stream_memopen(bufPtr, output_buffer_size);
|
|
|
|
Console.WriteLine("Ready to encode");
|
|
Console.WriteLine("jas_image_strtofmt(j2c)=" + jas_image_strtofmt("j2c"));
|
|
Console.WriteLine("jas_image_strtofmt(tif)=" + jas_image_strtofmt("tif"));
|
|
int retval = jas_image_encode(image_ptr, output_stream_ptr,
|
|
jas_image_strtofmt("j2c"), "");
|
|
|
|
jas_stream_flush(output_stream_ptr);
|
|
if (retval != 0) throw new Exception("Error encoding image: " + retval);
|
|
|
|
byte[] buf = new byte[output_buffer_size];
|
|
Marshal.Copy(bufPtr, buf, 0, output_buffer_size);
|
|
Marshal.FreeHGlobal(bufPtr);
|
|
|
|
jas_image_destroy(image_ptr);
|
|
|
|
jas_stream_close(input_stream_ptr);
|
|
|
|
return buf;
|
|
}
|
|
|
|
public static byte[] jasper_decode_j2c_to_tiff(byte[] input)
|
|
{
|
|
jasper_init();
|
|
|
|
int header_size = 1024; // a guess
|
|
IntPtr input_stream_ptr = jas_stream_memopen(input);
|
|
IntPtr temp_stream_ptr = jas_stream_tmpfile();
|
|
|
|
int format = jas_image_getfmt(input_stream_ptr);
|
|
|
|
Console.WriteLine("file is format # " + format);
|
|
|
|
IntPtr image_ptr = jas_image_decode(input_stream_ptr, format, "");
|
|
if (image_ptr == IntPtr.Zero) throw new Exception("Error decoding image");
|
|
jas_image_t image_struct = jas_image_t.fromPtr(image_ptr);
|
|
|
|
int output_buffer_size = image_struct.width * image_struct.height *
|
|
image_struct.numcmpts * 4 + 4096; // it's called a safety margin
|
|
|
|
IntPtr bufPtr = Marshal.AllocHGlobal(output_buffer_size);
|
|
IntPtr output_stream_ptr = jas_stream_memopen(bufPtr, output_buffer_size);
|
|
|
|
Console.WriteLine("Ready to encode");
|
|
Console.WriteLine("jas_image_strtofmt(j2c)=" + jas_image_strtofmt("j2c"));
|
|
Console.WriteLine("jas_image_strtofmt(tif)=" + jas_image_strtofmt("tif"));
|
|
int retval = jas_image_encode(image_ptr, temp_stream_ptr,
|
|
jas_image_strtofmt("tif"), "");
|
|
|
|
jas_stream_flush(temp_stream_ptr);
|
|
jas_stream_rewind(temp_stream_ptr);
|
|
jas_stream_copy(output_stream_ptr, temp_stream_ptr, -1);
|
|
jas_stream_flush(output_stream_ptr);
|
|
if (retval != 0) throw new Exception("Error encoding image: " + retval);
|
|
|
|
byte[] buf = new byte[output_buffer_size];
|
|
Marshal.Copy(bufPtr, buf, 0, output_buffer_size);
|
|
Marshal.FreeHGlobal(bufPtr);
|
|
|
|
jas_image_destroy(image_ptr);
|
|
|
|
// jas_stream_close(output_stream_ptr);
|
|
jas_stream_close(temp_stream_ptr);
|
|
jas_stream_close(input_stream_ptr);
|
|
|
|
return buf;
|
|
}
|
|
|
|
public static byte[] jasper_decode_j2c_to_tga(byte[] input)
|
|
{
|
|
jasper_init();
|
|
|
|
int header_size = 32; // roughly
|
|
IntPtr input_stream_ptr = jas_stream_memopen(input);
|
|
|
|
int format = jas_image_getfmt(input_stream_ptr);
|
|
|
|
Console.WriteLine("file is format # " + format);
|
|
|
|
IntPtr image_ptr = jas_image_decode(input_stream_ptr, format, "");
|
|
if (image_ptr == IntPtr.Zero) throw new Exception("Error decoding image");
|
|
|
|
jas_image_t image_struct = jas_image_t.fromPtr(image_ptr);
|
|
|
|
Console.WriteLine("image has " + image_struct.numcmpts + " components");
|
|
int[] mux_order = null;
|
|
switch (image_struct.numcmpts)
|
|
{
|
|
case 4: mux_order = new int[] { 2, 1, 0, 3 }; break; /* BGRA */
|
|
case 3: mux_order = new int[] { 2, 1, 0, -1 }; break; /* BGR1 */
|
|
case 2: mux_order = new int[] { 0, 0, 0, 1 }; break; /* GGGA */
|
|
case 1: mux_order = new int[] { 0, 0, 0, -1 }; break; /* GGG1 */
|
|
default: throw new Exception("Unhandled number of components:" + image_struct.numcmpts);
|
|
}
|
|
|
|
int[] pixels = get_multiplexed_image_data(image_ptr, mux_order);
|
|
byte[] output = new byte[image_struct.height * image_struct.width * 4 + header_size];
|
|
int offset = 0;
|
|
output[offset++] = 0; // idlength
|
|
output[offset++] = 0; // colormaptype = 0: no colormap
|
|
output[offset++] = 2; // image type = 2: uncompressed RGB
|
|
output[offset++] = 0; // color map spec is five zeroes for no color map
|
|
output[offset++] = 0; // color map spec is five zeroes for no color map
|
|
output[offset++] = 0; // color map spec is five zeroes for no color map
|
|
output[offset++] = 0; // color map spec is five zeroes for no color map
|
|
output[offset++] = 0; // color map spec is five zeroes for no color map
|
|
output[offset++] = 0; // x origin = two bytes
|
|
output[offset++] = 0; // x origin = two bytes
|
|
output[offset++] = 0; // y origin = two bytes
|
|
output[offset++] = 0; // y origin = two bytes
|
|
output[offset++] = (byte)(image_struct.width & 0xFF); // width - low byte
|
|
output[offset++] = (byte)(image_struct.width >> 8); // width - hi byte
|
|
output[offset++] = (byte)(image_struct.height & 0xFF); // height - low byte
|
|
output[offset++] = (byte)(image_struct.height >> 8); // height - hi byte
|
|
output[offset++] = 32; // 32 bits per pixel
|
|
output[offset++] = 40;//8; // image descriptor byte -- 8 bits of Alpha data per pixel
|
|
for (int i = 0; i < (image_struct.width * image_struct.height); i++)
|
|
{
|
|
output[offset++] = (byte)(pixels[i] & 0xFF); // red
|
|
output[offset++] = (byte)((pixels[i] >> 8) & 0xFF); // green
|
|
output[offset++] = (byte)((pixels[i] >> 16) & 0xFF); // blue
|
|
output[offset++] = (byte)((pixels[i] >> 24) & 0xFF); // alpha
|
|
}
|
|
|
|
jas_image_destroy(image_ptr);
|
|
jas_stream_close(input_stream_ptr);
|
|
|
|
return output;
|
|
}
|
|
|
|
public static void Main(string[] args)
|
|
{
|
|
jas_init();
|
|
Console.WriteLine("get_jasper_version=" + get_jasper_version());
|
|
jas_setdbglevel(1000);
|
|
|
|
if (args.Length == 1)
|
|
{
|
|
Console.WriteLine("Opening file: " + args[0]);
|
|
FileStream read_stream = new FileStream(args[0], FileMode.Open, FileAccess.Read);
|
|
BinaryReader binary_reader = new BinaryReader(read_stream);
|
|
byte[] j2c_data = binary_reader.ReadBytes((int)read_stream.Length);
|
|
binary_reader.Close();
|
|
read_stream.Close();
|
|
|
|
/* byte[] tga_data = jasper_decode_j2c_to_tga(j2c_data);
|
|
Console.WriteLine("Writing output to output.tga");
|
|
FileStream write_stream = new FileStream("output.tga", FileMode.Create);
|
|
write_stream.Write(tga_data, 0, tga_data.Length);
|
|
write_stream.Close(); */
|
|
|
|
|
|
byte[] tiff_data = jasper_decode_j2c_to_tiff(j2c_data);
|
|
Console.WriteLine("Writing output to output.tif");
|
|
FileStream write_stream = new FileStream("output.tif", FileMode.Create);
|
|
write_stream.Write(tiff_data, 0, tiff_data.Length);
|
|
write_stream.Close();
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|