122 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
/*
 | 
						|
 * format - Haxe File Formats
 | 
						|
 *
 | 
						|
 *  BMP File Format
 | 
						|
 *  Copyright (C) 2007-2009 Robert Sköld
 | 
						|
 *
 | 
						|
 * Copyright (c) 2009, The Haxe Project Contributors
 | 
						|
 * All rights reserved.
 | 
						|
 * Redistribution and use in source and binary forms, with or without
 | 
						|
 * modification, are permitted provided that the following conditions are met:
 | 
						|
 *
 | 
						|
 *   - Redistributions of source code must retain the above copyright
 | 
						|
 *     notice, this list of conditions and the following disclaimer.
 | 
						|
 *   - Redistributions in binary form must reproduce the above copyright
 | 
						|
 *     notice, this list of conditions and the following disclaimer in the
 | 
						|
 *     documentation and/or other materials provided with the distribution.
 | 
						|
 *
 | 
						|
 * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
 | 
						|
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
						|
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
						|
 * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
 | 
						|
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
						|
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
						|
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
						|
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
						|
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | 
						|
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 | 
						|
 * DAMAGE.
 | 
						|
 */
 | 
						|
 | 
						|
package iron.format.bmp;
 | 
						|
 | 
						|
import iron.format.bmp.Data;
 | 
						|
 | 
						|
 | 
						|
class Reader {
 | 
						|
 | 
						|
	var input : haxe.io.Input;
 | 
						|
 | 
						|
	public function new( i ) {
 | 
						|
		input = i;
 | 
						|
	}
 | 
						|
 | 
						|
	/** 
 | 
						|
	 * Only supports uncompressed 24bpp bitmaps (the most common format).
 | 
						|
	 * 
 | 
						|
	 * The returned bytes in `Data.pixels` will be in BGR order, and with padding (if present).
 | 
						|
	 * 
 | 
						|
	 * @see https://msdn.microsoft.com/en-us/library/windows/desktop/dd318229(v=vs.85).aspx
 | 
						|
	 * @see https://en.wikipedia.org/wiki/BMP_file_format#Bitmap_file_header
 | 
						|
	 */
 | 
						|
	public function read() : format.bmp.Data {
 | 
						|
		// Read Header
 | 
						|
		for (b in ["B".code, "M".code]) {
 | 
						|
			if (input.readByte() != b) throw "Invalid header";
 | 
						|
		}
 | 
						|
	
 | 
						|
		var fileSize = input.readInt32();
 | 
						|
		input.readInt32();							// Reserved
 | 
						|
		var offset = input.readInt32();
 | 
						|
 | 
						|
		// Read InfoHeader
 | 
						|
		var infoHeaderSize = input.readInt32();		// InfoHeader size
 | 
						|
		if (infoHeaderSize != 40) {
 | 
						|
			throw 'Info headers with size $infoHeaderSize not supported.';
 | 
						|
		}
 | 
						|
		var width = input.readInt32();				// Image width (actual, not padded)
 | 
						|
		var height = input.readInt32();				// Image height
 | 
						|
		var numPlanes = input.readInt16();			// Number of planes
 | 
						|
		var bits = input.readInt16();				// Bits per pixel
 | 
						|
		var compression = input.readInt32();		// Compression type
 | 
						|
		var dataLength = input.readInt32();			// Image data size (includes padding!)
 | 
						|
		input.readInt32();							// Horizontal resolution
 | 
						|
		input.readInt32();							// Vertical resolution
 | 
						|
		var colorsUsed = input.readInt32();			// Colors used (0 when uncompressed)
 | 
						|
		input.readInt32();							// Important colors (0 when uncompressed)
 | 
						|
 | 
						|
		// If there's no compression, the dataLength may be 0
 | 
						|
		if ( compression == 0 && dataLength == 0 ) dataLength = fileSize - offset;
 | 
						|
 | 
						|
		var bytesRead = 54; // total read above
 | 
						|
		
 | 
						|
		var colorTable : haxe.io.Bytes = null;
 | 
						|
		if ( bits <= 8 ) {
 | 
						|
			if ( colorsUsed == 0 ) {
 | 
						|
				colorsUsed = Tools.getNumColorsForBitDepth(bits);
 | 
						|
			}
 | 
						|
			var colorTableLength = 4 * colorsUsed;
 | 
						|
			colorTable = haxe.io.Bytes.alloc( colorTableLength );
 | 
						|
			input.readFullBytes( colorTable, 0, colorTableLength );
 | 
						|
			bytesRead += colorTableLength;
 | 
						|
		}
 | 
						|
 | 
						|
		input.read( offset - bytesRead );
 | 
						|
		
 | 
						|
		var p = haxe.io.Bytes.alloc( dataLength );	
 | 
						|
		
 | 
						|
		// Read Raster Data
 | 
						|
		var paddedStride = Tools.computePaddedStride(width, bits);
 | 
						|
		var topToBottom = false;
 | 
						|
		if ( height < 0 ) { // if bitmap is stored top to bottom
 | 
						|
			topToBottom = true;
 | 
						|
			height = -height;
 | 
						|
		}
 | 
						|
    
 | 
						|
		input.readFullBytes(p, 0, dataLength);
 | 
						|
			
 | 
						|
		return {
 | 
						|
			header: {
 | 
						|
				width: width,
 | 
						|
				height: height,
 | 
						|
				paddedStride: paddedStride,
 | 
						|
				topToBottom: topToBottom,
 | 
						|
				bpp: bits,
 | 
						|
				dataLength: dataLength,
 | 
						|
				compression: compression
 | 
						|
			},
 | 
						|
			pixels: p,
 | 
						|
			colorTable: colorTable
 | 
						|
		}
 | 
						|
	}
 | 
						|
} |