Esempio n. 1
0
 public static void VerifyPixelSizeMatchesImageDimensionsWithPitch(ushort bitCount, int width, int height, int pixelsWithPitchSize)
 {
     if (pixelsWithPitchSize < ImageHeader.CalculatePitch(bitCount, width) * System.Math.Abs(height))
     {
         throw new System.Exception("The size of pixels does not match the image's height time pitch");
     }
 }
Esempio n. 2
0
        /// <summary>
        /// Create default indexed bitmap with palette.
        /// </summary>
        public BitmapFile(ushort bitCount, uint width, int height, Color[] palette) : this(bitCount, width, height)
        {
            if (palette.Length > 1 << bitCount)
            {
                throw new System.Exception("Unable to create bitmap. Provided palette length is greater than provided bit count.");
            }

            // Expand palette, if needed
            int maxSize = ImageHeader.CalcMaxIndexedPaletteSize(bitCount);

            if (palette.Length != maxSize)
            {
                Color[] newPalette = new Color[maxSize];
                System.Array.Copy(palette, newPalette, palette.Length < newPalette.Length ? palette.Length : newPalette.Length);

                palette = newPalette;
            }

            // Create headers
            int pixelOffset = BmpHeader.SizeInBytes + ImageHeader.SizeInBytes + palette.Length * Color.SizeInBytes;
            int fileSize    = pixelOffset + ImageHeader.CalculatePitch(bitCount, (int)width) * System.Math.Abs(height);

            bmpHeader   = BmpHeader.Create((uint)fileSize, (uint)pixelOffset);
            imageHeader = ImageHeader.Create((int)width, height, bitCount);

            // Store data
            this.palette = palette;
        }
Esempio n. 3
0
        // Write
        private static void WriteHeaders(BinaryWriter seekableWriter, ushort bitCount, int width, int height, Color[] palette)
        {
            int pixelOffset = BmpHeader.SizeInBytes + ImageHeader.SizeInBytes + palette.Length * Color.SizeInBytes;
            int fileSize    = pixelOffset + ImageHeader.CalculatePitch(bitCount, width) * System.Math.Abs(height);

            //if (fileSize > uint.MaxValue) {
            //	throw new System.Exception("Bitmap size is too large to save to disk.");
            //}

            BmpHeader   bmpHeader   = BmpHeader.Create((uint)fileSize, (uint)pixelOffset);
            ImageHeader imageHeader = ImageHeader.Create(width, height, bitCount);

            bmpHeader.Serialize(seekableWriter);
            imageHeader.Serialize(seekableWriter);
        }
Esempio n. 4
0
        private static void WritePixels(BinaryWriter seekableWriter, byte[] pixels, int width, int height, ushort bitCount)
        {
            height = System.Math.Abs(height);

            int pitch = ImageHeader.CalculatePitch(bitCount, width);
            int bytesOfPixelsPerRow = ImageHeader.CalcPixelByteWidth(bitCount, width);

            byte[] padding = new byte[pitch - bytesOfPixelsPerRow];

            //for (int i = 0; i+bytesOfPixelsPerRow <= pixels.Length; i += pitch) {
            for (int y = 0; y < height; ++y)
            {
                seekableWriter.Write(pixels, y * pitch, bytesOfPixelsPerRow);
                seekableWriter.Write(padding);
            }
        }
Esempio n. 5
0
        public void InvertScanLines()
        {
            imageHeader.height *= -1;

            byte[] invertedPixels = new byte[pixels.Length];

            int pitch = imageHeader.CalculatePitch();

            for (int row = AbsoluteHeight() - 1, destIndex = 0; row >= 0; --row)
            {
                int srcIndex   = row * pitch;
                int copyLength = pitch;
                System.Array.Copy(pixels, srcIndex, invertedPixels, destIndex, copyLength);
                destIndex += copyLength;
            }

            pixels = invertedPixels;
        }
Esempio n. 6
0
        /// <summary>
        /// Create default indexed bitmap.
        /// </summary>
        public BitmapFile(ushort bitCount, uint width, int height)
        {
            VerifyIndexedImageForSerialization(bitCount);

            // Create headers and default palette
            imageHeader = ImageHeader.Create((int)width, (int)height, bitCount);
            palette     = new Color[imageHeader.CalcMaxIndexedPaletteSize()];
            pixels      = new byte[imageHeader.CalculatePitch() * System.Math.Abs(height)];

            int pixelOffset    = BmpHeader.SizeInBytes + ImageHeader.SizeInBytes + palette.Length * Color.SizeInBytes;
            int bitmapFileSize = pixelOffset + pixels.Length * sizeof(byte);

            //if (bitmapFileSize > uint.MaxValue) {
            //	throw new System.Exception("Maximum size of a bitmap file has been exceeded");
            //}

            bmpHeader = BmpHeader.Create((uint)bitmapFileSize, (uint)pixelOffset);
        }
Esempio n. 7
0
        public void SetPixel(int x, int y, int paletteIndex)
        {
            int pitch = ImageHeader.CalculatePitch(imageHeader.bitCount, imageHeader.width);

            int row        = y * pitch;                                 // The row of the pixel to set
            int bitOffset  = x * imageHeader.bitCount;                  // The bit offset in the row
            int byteOffset = bitOffset / 8;                             // The byte offset in the row
            int index      = row + byteOffset;                          // The index to set

            // The bit offset relative to the byte offset
            // The pixels are stored with most-significant first
            bitOffset %= 8;
            bitOffset  = 8 - (bitOffset + imageHeader.bitCount);

            // A mask for the bits to set for the byte at the "index" in the pixel array
            int mask = ~(~0 << imageHeader.bitCount) << bitOffset;

            // NOTE:
            // We are assuming that the pixel will not fall between bytes (e.g. 2 bits on index 1 and 2 bits on index 2).
            // This is a safe assumption for 1, 2, 4, and 8 bits per pixel.
            pixels[index] &= (byte)~mask;                                // Clear masked bits
            pixels[index] |= (byte)((paletteIndex << bitOffset) & mask); // Insert masked palette index
        }