public static Image DecodeWithBump(byte[] buffer, out byte[] bump, bool decodebump = true) { if (!J2cInit.m_Inited) { J2cInit.InitOpenJP2(); } bump = null; int width; int height; int channels; int channelwidth; int[] red; int[] green; int[] blue; int[] alpha = null; { /* shorten the j2c decode context variable visibility here */ IntPtr ptr = J2cDecode(buffer, buffer.Length); if (ptr == IntPtr.Zero) { throw new J2cDecodingFailedException(); } try { width = J2cDecodedGetWidth(ptr); height = J2cDecodedGetHeight(ptr); channels = J2cDecodedGetChannels(ptr); if (channels == 0) { throw new J2cDecodingFailedException(); } channelwidth = width * height; red = new int[channelwidth]; alpha = null; switch (channels) { case 1: Marshal.Copy(J2cDecodedGetScan0(ptr, 0), red, 0, channelwidth); green = red; blue = red; break; case 2: Marshal.Copy(J2cDecodedGetScan0(ptr, 0), red, 0, channelwidth); green = red; blue = red; alpha = new int[channelwidth]; Marshal.Copy(J2cDecodedGetScan0(ptr, 1), alpha, 0, channelwidth); break; case 3: green = new int[channelwidth]; blue = new int[channelwidth]; Marshal.Copy(J2cDecodedGetScan0(ptr, 0), red, 0, channelwidth); Marshal.Copy(J2cDecodedGetScan0(ptr, 1), green, 0, channelwidth); Marshal.Copy(J2cDecodedGetScan0(ptr, 2), blue, 0, channelwidth); break; default: alpha = new int[channelwidth]; Marshal.Copy(J2cDecodedGetScan0(ptr, 3), alpha, 0, channelwidth); goto case 3; } if (channels > 4 && decodebump) { bump = new byte[channelwidth]; var ibump = new int[channelwidth]; Marshal.Copy(J2cDecodedGetScan0(ptr, 4), ibump, 0, channelwidth); for (int i = 0; i < channelwidth; ++i) { bump[i] = (byte)ibump[i]; } } } finally { J2cDecodedFree(ptr); } } /* transform input channels to actual Image data */ byte[] imagedata; int destpos = 0; PixelFormat destformat; if (alpha != null) { destformat = PixelFormat.Format32bppArgb; imagedata = new byte[channelwidth * 4]; for (int i = 0; i < channelwidth; ++i) { imagedata[destpos++] = (byte)blue[i]; imagedata[destpos++] = (byte)green[i]; imagedata[destpos++] = (byte)red[i]; imagedata[destpos++] = (byte)alpha[i]; } } else { destformat = PixelFormat.Format24bppRgb; imagedata = new byte[channelwidth * 3]; for (int i = 0; i < channelwidth; ++i) { imagedata[destpos++] = (byte)blue[i]; imagedata[destpos++] = (byte)green[i]; imagedata[destpos++] = (byte)red[i]; } } /* no using here, we are returning it */ var bmp = new Bitmap(width, height, destformat); /* put the decoded image into it */ BitmapData lockBits = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, destformat); Marshal.Copy(imagedata, 0, lockBits.Scan0, imagedata.Length); bmp.UnlockBits(lockBits); return(bmp); }
public static byte[] EncodeWithBump(Bitmap img, bool lossless, byte[] bumpdata) { if (!J2cInit.m_Inited) { J2cInit.InitOpenJP2(); } int imgChannelWidth = img.Width * img.Height; if (bumpdata.Length != imgChannelWidth) { throw new ArgumentException("bumpdata does not match channel byte size"); } const int channels = 5; byte[] datastream; if (img.PixelFormat == PixelFormat.Format32bppArgb) { datastream = new byte[imgChannelWidth * channels]; int pixpos = 0; int bumppos = 0; for (int y = 0; y < img.Height; ++y) { for (int x = 0; x < img.Width; ++x) { Color c = img.GetPixel(x, y); datastream[pixpos++] = c.R; datastream[pixpos++] = c.G; datastream[pixpos++] = c.B; datastream[pixpos++] = c.A; datastream[pixpos++] = bumpdata[bumppos++]; } } } else if (img.PixelFormat == PixelFormat.Format24bppRgb) { datastream = new byte[imgChannelWidth * channels]; int pixpos = 0; int bumppos = 0; for (int y = 0; y < img.Height; ++y) { for (int x = 0; x < img.Width; ++x) { Color c = img.GetPixel(x, y); datastream[pixpos++] = c.R; datastream[pixpos++] = c.G; datastream[pixpos++] = c.B; datastream[pixpos++] = 255; datastream[pixpos++] = bumpdata[bumppos++]; } } } else { throw new J2cEncodingFailedException(); } IntPtr nativePtr = J2cEncode(datastream, img.Width, img.Height, channels, lossless); if (nativePtr == IntPtr.Zero) { throw new J2cEncodingFailedException(); } byte[] j2cstream; try { j2cstream = new byte[J2cEncodedGetLength(nativePtr)]; if (j2cstream.Length != J2cEncodedRead(nativePtr, j2cstream, j2cstream.Length)) { throw new J2cEncodingFailedException(); } } finally { J2cEncodedFree(nativePtr); } return(j2cstream); }