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);
    }
    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 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 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;
 }
    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);
    }