예제 #1
0
        // Load a JPEG image from the specified stream.  The first 4 bytes
        // have already been read and discarded.
        public static void Load(Stream stream, Image image,
                                byte[] prime, int primeLen)
        {
            // Determine if we actually have the JPEG library.
            if (!JpegLib.JpegLibraryPresent())
            {
                throw new FormatException("libjpeg is not available");
            }

            // Create the decompression object.
            JpegLib.jpeg_decompress_struct cinfo;
            cinfo     = new JpegLib.jpeg_decompress_struct();
            cinfo.err = JpegLib.CreateErrorHandler();
            JpegLib.jpeg_create_decompress(ref cinfo);

            // Initialize the source manager.
            JpegLib.StreamToSourceManager
                (ref cinfo, stream, prime, primeLen);

            // Read the JPEG header.
            JpegLib.jpeg_read_header(ref cinfo, (Int)1);

            // Set the decompression parameters the way we want them.
            cinfo.out_color_space = JpegLib.J_COLOR_SPACE.JCS_RGB;

            // Start the decompression process.
            JpegLib.jpeg_start_decompress(ref cinfo);

            // Initialize the image to 24-bit RGB, to match the JPEG file.
            image.Width       = (int)(cinfo.output_width);
            image.Height      = (int)(cinfo.output_height);
            image.PixelFormat = PixelFormat.Format24bppRgb;
            if (prime[3] == 0xE1)
            {
                image.LoadFormat = Image.Exif;
            }
            else
            {
                image.LoadFormat = Image.Jpeg;
            }
            Frame frame = image.AddFrame();

            // Read the scanlines from the image.
            int posn, width, offset, stride, y, twidth;

            width  = frame.Width;
            twidth = width * 3;
            stride = frame.Stride;
            byte[] data = frame.Data;
            IntPtr buf  = Marshal.AllocHGlobal(width * 3);
            byte * pbuf = (byte *)buf;

            y = 0;
            while (((int)(cinfo.output_scanline)) <
                   ((int)(cinfo.output_height)))
            {
                JpegLib.jpeg_read_scanlines
                    (ref cinfo, ref buf, (UInt)1);
                offset = (y++) * stride;
                for (posn = 0; posn < twidth; posn += 3)
                {
                    // Convert the JPEG RGB data into BGR for the frame.
                    data[offset]     = pbuf[posn + 2];
                    data[offset + 1] = pbuf[posn + 1];
                    data[offset + 2] = pbuf[posn];
                    offset          += 3;
                }
            }
            Marshal.FreeHGlobal(buf);

            // Finish the decompression process.
            JpegLib.jpeg_finish_decompress(ref cinfo);

            // Clean everything up.
            JpegLib.FreeSourceManager(ref cinfo);
            JpegLib.jpeg_destroy_decompress(ref cinfo);
            JpegLib.FreeErrorHandler(cinfo.err);
        }
예제 #2
0
파일: JpegWriter.cs 프로젝트: ForNeVeR/pnet
        // Save a JPEG image to the specified stream.
        public static void Save(Stream stream, Image image)
        {
            // Determine if we actually have the JPEG library.
            if (!JpegLib.JpegLibraryPresent())
            {
                throw new FormatException("libjpeg is not available");
            }

            // Create the compression object.
            JpegLib.jpeg_compress_struct cinfo;
            cinfo     = new JpegLib.jpeg_compress_struct();
            cinfo.err = JpegLib.CreateErrorHandler();
            JpegLib.jpeg_create_compress(ref cinfo);

            // Initialize the destination manager.
            JpegLib.StreamToDestinationManager(ref cinfo, stream);

            // Get the frame to be written.
            Frame frame = image.GetFrame(0);

            // Set the JPEG compression parameters.
            cinfo.image_width      = (UInt)(frame.Width);
            cinfo.image_height     = (UInt)(frame.Height);
            cinfo.input_components = (Int)3;
            cinfo.in_color_space   = JpegLib.J_COLOR_SPACE.JCS_RGB;
            JpegLib.jpeg_set_defaults(ref cinfo);

            // Start the compression process.
            JpegLib.jpeg_start_compress(ref cinfo, (Int)1);

            // Write the scanlines to the image.
            int posn, width, offset, stride;

            width  = frame.Width;
            stride = frame.Stride;
            byte[]      data   = frame.Data;
            PixelFormat format = frame.PixelFormat;
            IntPtr      buf    = Marshal.AllocHGlobal(width * 3);
            byte *      pbuf   = (byte *)buf;

            while (((int)(cinfo.next_scanline)) <
                   ((int)(cinfo.image_height)))
            {
                // Convert the source scanline into the JCS_RGB format.
                offset = ((int)(cinfo.next_scanline)) * stride;
                switch (format)
                {
                case PixelFormat.Format16bppRgb555:
                case PixelFormat.Format16bppArgb1555:
                {
                    Rgb555(data, offset, width, pbuf);
                }
                break;

                case PixelFormat.Format16bppRgb565:
                {
                    Rgb565(data, offset, width, pbuf);
                }
                break;

                case PixelFormat.Format24bppRgb:
                {
                    Rgb24bpp(data, offset, width, pbuf);
                }
                break;

                case PixelFormat.Format32bppRgb:
                case PixelFormat.Format32bppArgb:
                case PixelFormat.Format32bppPArgb:
                {
                    Rgb32bpp(data, offset, width, pbuf);
                }
                break;

                case PixelFormat.Format1bppIndexed:
                {
                    Rgb1bpp(data, offset, width, pbuf, frame.Palette);
                }
                break;

                case PixelFormat.Format4bppIndexed:
                {
                    Rgb4bpp(data, offset, width, pbuf, frame.Palette);
                }
                break;

                case PixelFormat.Format8bppIndexed:
                {
                    Rgb8bpp(data, offset, width, pbuf, frame.Palette);
                }
                break;

                case PixelFormat.Format16bppGrayScale:
                {
                    GrayScale16bpp(data, offset, width, pbuf);
                }
                break;

                case PixelFormat.Format48bppRgb:
                {
                    Rgb48bpp(data, offset, width, pbuf);
                }
                break;

                case PixelFormat.Format64bppPArgb:
                case PixelFormat.Format64bppArgb:
                {
                    Rgb64bpp(data, offset, width, pbuf);
                }
                break;
                }

                // Write the scanline to the buffer.
                JpegLib.jpeg_write_scanlines
                    (ref cinfo, ref buf, (UInt)1);
            }
            Marshal.FreeHGlobal(buf);

            // Finish the compression process.
            JpegLib.jpeg_finish_compress(ref cinfo);

            // Clean everything up.
            JpegLib.FreeDestinationManager(ref cinfo);
            JpegLib.jpeg_destroy_compress(ref cinfo);
            JpegLib.FreeErrorHandler(cinfo.err);
        }