示例#1
0
        /// <summary>
        /// This method loads the image into whole_image during the first call on
        /// get_pixel_rows.
        /// </summary>
        private int preload_image()
        {
            cdjpeg_progress_mgr progress = cinfo.Progress as cdjpeg_progress_mgr;

            /* Read the data into a virtual array in input-file row order. */
            for (int row = 0; row < cinfo.Image_height; row++)
            {
                if (progress != null)
                {
                    progress.Pass_counter = row;
                    progress.Pass_limit   = cinfo.Image_height;
                    progress.Updated();
                }

                byte[][] image_ptr  = whole_image.Access(row, 1);
                int      imageIndex = 0;
                for (int col = row_width; col > 0; col--)
                {
                    /* inline copy of read_byte() for speed */
                    int c = input_file.ReadByte();
                    if (c == -1)
                    {
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_INPUT_EOF);
                    }

                    image_ptr[0][imageIndex] = (byte)c;
                    imageIndex++;
                }
            }

            if (progress != null)
            {
                progress.completed_extra_passes++;
            }

            /* Set up to read from the virtual array in top-to-bottom order */
            switch (bits_per_pixel)
            {
            case 8:
                m_pixelRowsMethod = PixelRowsMethod.use8bit;
                break;

            case 24:
                m_pixelRowsMethod = PixelRowsMethod.use24bit;
                break;

            case 32:
                m_pixelRowsMethod = PixelRowsMethod.use32bit;
                break;

            default:
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADDEPTH);
                break;
            }

            source_row = cinfo.Image_height;

            /* And read the first row */
            return(get_pixel_rows());
        }
示例#2
0
        /// <summary>
        /// Read the file header; detects image size and component count.
        /// </summary>
        public override void start_input()
        {
            byte[] bmpfileheader = new byte[14];
            /* Read and verify the bitmap file header */
            if (!ReadOK(input_file, bmpfileheader, 0, 14))
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_INPUT_EOF);

            if (GET_2B(bmpfileheader, 0) != 0x4D42) /* 'BM' */
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_NOT);
            
            int bfOffBits = GET_4B(bmpfileheader, 10);
            /* We ignore the remaining fileheader fields */

            /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
             * or 64 bytes (OS/2 2.x).  Check the first 4 bytes to find out which.
             */
            byte[] bmpinfoheader = new byte[64];
            if (!ReadOK(input_file, bmpinfoheader, 0, 4))
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_INPUT_EOF);

            int headerSize = GET_4B(bmpinfoheader, 0);
            if (headerSize < 12 || headerSize> 64)
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADHEADER);

            if (!ReadOK(input_file, bmpinfoheader, 4, headerSize - 4))
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_INPUT_EOF);

            int biWidth = 0;      /* initialize to avoid compiler warning */
            int biHeight = 0;
            int biPlanes;
            int biCompression;
            int biXPelsPerMeter;
            int biYPelsPerMeter;
            int biClrUsed = 0;
            int mapentrysize = 0;       /* 0 indicates no colormap */
            switch (headerSize)
            {
                case 12:
                    /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */
                    biWidth = GET_2B(bmpinfoheader, 4);
                    biHeight = GET_2B(bmpinfoheader, 6);
                    biPlanes = GET_2B(bmpinfoheader, 8);
                    bits_per_pixel = GET_2B(bmpinfoheader, 10);

                    switch (bits_per_pixel)
                    {
                        case 8:
                            /* colormapped image */
                            mapentrysize = 3;       /* OS/2 uses RGBTRIPLE colormap */
                            cinfo.TRACEMS(1, (int)ADDON_MESSAGE_CODE.JTRC_BMP_OS2_MAPPED, biWidth, biHeight);
                            break;
                        case 24:
                            /* RGB image */
                            cinfo.TRACEMS(1, (int)ADDON_MESSAGE_CODE.JTRC_BMP_OS2, biWidth, biHeight);
                            break;
                        default:
                            cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADDEPTH);
                            break;
                    }

                    if (biPlanes != 1)
                        cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADPLANES);
                    break;
                case 40:
                case 64:
                    /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */
                    /* or OS/2 2.x header, which has additional fields that we ignore */
                    biWidth = GET_4B(bmpinfoheader, 4);
                    biHeight = GET_4B(bmpinfoheader, 8);
                    biPlanes = GET_2B(bmpinfoheader, 12);
                    bits_per_pixel = GET_2B(bmpinfoheader, 14);
                    biCompression = GET_4B(bmpinfoheader, 16);
                    biXPelsPerMeter = GET_4B(bmpinfoheader, 24);
                    biYPelsPerMeter = GET_4B(bmpinfoheader, 28);
                    biClrUsed = GET_4B(bmpinfoheader, 32);
                    /* biSizeImage, biClrImportant fields are ignored */

                    switch (bits_per_pixel)
                    {
                        case 8:
                            /* colormapped image */
                            mapentrysize = 4;       /* Windows uses RGBQUAD colormap */
                            cinfo.TRACEMS(1, (int)ADDON_MESSAGE_CODE.JTRC_BMP_MAPPED, biWidth, biHeight);
                            break;
                        case 24:
                            /* RGB image */
                            cinfo.TRACEMS(1, (int)ADDON_MESSAGE_CODE.JTRC_BMP, biWidth, biHeight);
                            break;
                        default:
                            cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADDEPTH);
                            break;
                    }

                    if (biPlanes != 1)
                        cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADPLANES);
                    
                    if (biCompression != 0)
                        cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_COMPRESSED);

                    if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0)
                    {
                        /* Set JFIF density parameters from the BMP data */
                        cinfo.X_density = (short)(biXPelsPerMeter / 100); /* 100 cm per meter */
                        cinfo.Y_density = (short)(biYPelsPerMeter / 100);
                        cinfo.Density_unit = DensityUnit.DotsCm;
                    }
                    break;
                default:
                    cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADHEADER);
                    break;
            }

            /* Compute distance to bitmap data --- will adjust for colormap below */
            int bPad = bfOffBits - (headerSize + 14);

            /* Read the colormap, if any */
            if (mapentrysize > 0)
            {
                if (biClrUsed <= 0)
                    biClrUsed = 256;        /* assume it's 256 */
                else if (biClrUsed > 256)
                    cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADCMAP);

                /* Allocate space to store the colormap */
                colormap = jpeg_common_struct.AllocJpegSamples(biClrUsed, 3);
                /* and read it from the file */
                read_colormap(biClrUsed, mapentrysize);
                /* account for size of colormap */
                bPad -= biClrUsed * mapentrysize;
            }

            /* Skip any remaining pad bytes */
            if (bPad < 0)           /* incorrect bfOffBits value? */
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADHEADER);

            while (--bPad >= 0)
                read_byte();

            /* Compute row width in file, including padding to 4-byte boundary */
            if (bits_per_pixel == 24)
                row_width = biWidth * 3;
            else
                row_width = biWidth;

            while ((row_width & 3) != 0)
                row_width++;

            /* Allocate space for inversion array, prepare for preload pass */
            whole_image = jpeg_common_struct.CreateSamplesArray(row_width, biHeight);
            whole_image.ErrorProcessor = cinfo;
            m_pixelRowsMethod = PixelRowsMethod.preload;
            if (cinfo.Progress != null)
            {
                cdjpeg_progress_mgr progress = cinfo.Progress as cdjpeg_progress_mgr;
                if (progress != null)
                {
                    /* count file input as separate pass */
                    progress.total_extra_passes++;
                }
            }

            /* Allocate one-row buffer for returned data */
            buffer = jpeg_common_struct.AllocJpegSamples(biWidth * 3, 1);
            buffer_height = 1;

            cinfo.In_color_space = J_COLOR_SPACE.JCS_RGB;
            cinfo.Input_components = 3;
            cinfo.Data_precision = 8;
            cinfo.Image_width = biWidth;
            cinfo.Image_height = biHeight;
        }
示例#3
0
        /// <summary>
        /// This method loads the image into whole_image during the first call on
        /// get_pixel_rows. 
        /// </summary>
        private int preload_image()
        {
            cdjpeg_progress_mgr progress = cinfo.Progress as cdjpeg_progress_mgr;

            /* Read the data into a virtual array in input-file row order. */
            for (int row = 0; row < cinfo.Image_height; row++)
            {
                if (progress != null)
                {
                    progress.Pass_counter = row;
                    progress.Pass_limit = cinfo.Image_height;
                    progress.Updated();
                }

                byte[][] image_ptr = whole_image.Access(row, 1);
                int imageIndex = 0;
                for (int col = row_width; col > 0; col--)
                {
                    /* inline copy of read_byte() for speed */
                    int c = input_file.ReadByte();
                    if (c == -1)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_INPUT_EOF);

                    image_ptr[0][imageIndex] = (byte)c;
                    imageIndex++;
                }
            }

            if (progress != null)
                progress.completed_extra_passes++;

            /* Set up to read from the virtual array in top-to-bottom order */
            switch (bits_per_pixel)
            {
                case 8:
                    m_pixelRowsMethod = PixelRowsMethod.use8bit;
                    break;
                case 24:
                    m_pixelRowsMethod = PixelRowsMethod.use24bit;
                    break;
                default:
                    cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADDEPTH);
                    break;
            }

            source_row = cinfo.Image_height;

            /* And read the first row */
            return get_pixel_rows();
        }
示例#4
0
        /// <summary>
        /// Read the file header; detects image size and component count.
        /// </summary>
        public override void start_input()
        {
            byte[] bmpfileheader = new byte[14];
            /* Read and verify the bitmap file header */
            if (!ReadOK(input_file, bmpfileheader, 0, 14))
            {
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_INPUT_EOF);
            }

            if (GET_2B(bmpfileheader, 0) != 0x4D42) /* 'BM' */
            {
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_NOT);
            }

            int bfOffBits = GET_4B(bmpfileheader, 10);

            /* We ignore the remaining fileheader fields */

            /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
             * or 64 bytes (OS/2 2.x).  Check the first 4 bytes to find out which.
             */
            byte[] bmpinfoheader = new byte[64];
            if (!ReadOK(input_file, bmpinfoheader, 0, 4))
            {
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_INPUT_EOF);
            }

            int headerSize = GET_4B(bmpinfoheader, 0);

            if (headerSize < 12 || headerSize > 64)
            {
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADHEADER);
            }

            if (!ReadOK(input_file, bmpinfoheader, 4, headerSize - 4))
            {
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_INPUT_EOF);
            }

            int biWidth  = 0;     /* initialize to avoid compiler warning */
            int biHeight = 0;
            int biPlanes = 0;
            int biCompression;
            int biXPelsPerMeter;
            int biYPelsPerMeter;
            int biClrUsed    = 0;
            int mapentrysize = 0;       /* 0 indicates no colormap */

            switch (headerSize)
            {
            case 12:
                /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */
                biWidth        = GET_2B(bmpinfoheader, 4);
                biHeight       = GET_2B(bmpinfoheader, 6);
                biPlanes       = GET_2B(bmpinfoheader, 8);
                bits_per_pixel = GET_2B(bmpinfoheader, 10);

                switch (bits_per_pixel)
                {
                case 8:
                    /* colormapped image */
                    mapentrysize = 3;               /* OS/2 uses RGBTRIPLE colormap */
                    cinfo.TRACEMS(1, (int)ADDON_MESSAGE_CODE.JTRC_BMP_OS2_MAPPED, biWidth, biHeight);
                    break;

                case 24:
                    /* RGB image */
                    cinfo.TRACEMS(1, (int)ADDON_MESSAGE_CODE.JTRC_BMP_OS2, biWidth, biHeight);
                    break;

                default:
                    cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADDEPTH);
                    break;
                }

                break;

            case 40:
            case 64:
                /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */
                /* or OS/2 2.x header, which has additional fields that we ignore */
                biWidth         = GET_4B(bmpinfoheader, 4);
                biHeight        = GET_4B(bmpinfoheader, 8);
                biPlanes        = GET_2B(bmpinfoheader, 12);
                bits_per_pixel  = GET_2B(bmpinfoheader, 14);
                biCompression   = GET_4B(bmpinfoheader, 16);
                biXPelsPerMeter = GET_4B(bmpinfoheader, 24);
                biYPelsPerMeter = GET_4B(bmpinfoheader, 28);
                biClrUsed       = GET_4B(bmpinfoheader, 32);
                /* biSizeImage, biClrImportant fields are ignored */

                switch (bits_per_pixel)
                {
                case 8:
                    /* colormapped image */
                    mapentrysize = 4;               /* Windows uses RGBQUAD colormap */
                    cinfo.TRACEMS(1, (int)ADDON_MESSAGE_CODE.JTRC_BMP_MAPPED, biWidth, biHeight);
                    break;

                case 24:
                    /* RGB image */
                    cinfo.TRACEMS(1, (int)ADDON_MESSAGE_CODE.JTRC_BMP, biWidth, biHeight);
                    break;

                case 32:
                    /* RGB image + Alpha channel */
                    cinfo.TRACEMS(1, (int)ADDON_MESSAGE_CODE.JTRC_BMP, biWidth, biHeight);
                    break;

                default:
                    cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADDEPTH);
                    break;
                }

                if (biCompression != 0)
                {
                    cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_COMPRESSED);
                }

                if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0)
                {
                    /* Set JFIF density parameters from the BMP data */
                    cinfo.X_density    = (short)(biXPelsPerMeter / 100);  /* 100 cm per meter */
                    cinfo.Y_density    = (short)(biYPelsPerMeter / 100);
                    cinfo.Density_unit = DensityUnit.DotsCm;
                }
                break;

            default:
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADHEADER);
                break;
            }

            if (biWidth <= 0 || biHeight <= 0)
            {
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_EMPTY);
            }

            if (biPlanes != 1)
            {
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADPLANES);
            }

            /* Compute distance to bitmap data --- will adjust for colormap below */
            int bPad = bfOffBits - (headerSize + 14);

            /* Read the colormap, if any */
            if (mapentrysize > 0)
            {
                if (biClrUsed <= 0)
                {
                    biClrUsed = 256;        /* assume it's 256 */
                }
                else if (biClrUsed > 256)
                {
                    cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADCMAP);
                }

                /* Allocate space to store the colormap */
                colormap = jpeg_common_struct.AllocJpegSamples(biClrUsed, 3);
                /* and read it from the file */
                read_colormap(biClrUsed, mapentrysize);
                /* account for size of colormap */
                bPad -= biClrUsed * mapentrysize;
            }

            /* Skip any remaining pad bytes */
            if (bPad < 0)           /* incorrect bfOffBits value? */
            {
                cinfo.ERREXIT((int)ADDON_MESSAGE_CODE.JERR_BMP_BADHEADER);
            }

            while (--bPad >= 0)
            {
                read_byte();
            }

            /* Compute row width in file, including padding to 4-byte boundary */
            if (bits_per_pixel == 24)
            {
                row_width = biWidth * 3;
            }
            else if (bits_per_pixel == 32)
            {
                row_width = biWidth * 4;
            }
            else
            {
                row_width = biWidth;
            }

            while ((row_width & 3) != 0)
            {
                row_width++;
            }

            /* Allocate space for inversion array, prepare for preload pass */
            whole_image = jpeg_common_struct.CreateSamplesArray(row_width, biHeight);
            whole_image.ErrorProcessor = cinfo;

            m_pixelRowsMethod = PixelRowsMethod.preload;
            if (cinfo.Progress != null)
            {
                cdjpeg_progress_mgr progress = cinfo.Progress as cdjpeg_progress_mgr;
                if (progress != null)
                {
                    /* count file input as separate pass */
                    progress.total_extra_passes++;
                }
            }

            /* Allocate one-row buffer for returned data */
            buffer        = jpeg_common_struct.AllocJpegSamples(biWidth * 3, 1);
            buffer_height = 1;

            cinfo.In_color_space   = J_COLOR_SPACE.JCS_RGB;
            cinfo.Input_components = 3;
            cinfo.Data_precision   = 8;
            cinfo.Image_width      = biWidth;
            cinfo.Image_height     = biHeight;
        }