Getting header info of a BMP file

M

mmcclaf

Does anyone know how to get all of the header file from a .BMP file
using java?
 
M

mmcclaf

Have a look at the ImageInfo class part of common11. Seehttp://mindprod.com/products1.html#COMMON11

It handles PNG, GIF and JPG. IF you had docs on BMP format, you could
get info in a similar way.

I took a look at them but I'm still having troubles with a
FileInputStream, or perhaps its the understanding of how it works. And
then the trouble of trying to split it up into the different sections.
HAs anyone done anything like this with coding before?
 
R

Roedy Green

I took a look at them but I'm still having troubles with a
FileInputStream, or perhaps its the understanding of how it works.

DataInputStream just reads big endian binary fields sequentially.
LEDataInputStrem reads little endian binary fields sequentially. You
can skip over stuff you don't want.
 
R

Roedy Green

HAs anyone done anything like this with coding before?

The other way to do it is to read in a batch of raw bytes, then
compose the fields. See http://mindprod.com/jgloss/endian for code to
do that.

What info do you need? I could give you an estimate for writing the
code. If all you want is ImageInfo to handle getting the size of a
BMP image, I would do that for $20.
 
J

Jeff Higgins

I took a look at them but I'm still having troubles with a
FileInputStream, or perhaps its the understanding of how it works. And
then the trouble of trying to split it up into the different sections.
HAs anyone done anything like this with coding before?

There may be easier ways of getting the information you seek,
but just as a kick-start:

[TODO: needs work]

import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.BitSet;

public class BMPTest {

public static void main(String[] args)
throws Exception {

File file = new File(args[0]);
byte[] fileHeaderBytes = new byte[14];
byte[] infoSizeBytes = new byte[4];
int infoSize;
byte[] infoHeader;
InfoHeader header;

FileInputStream inputStream =
new FileInputStream(file);
inputStream.read(fileHeaderBytes);
inputStream.read(infoSizeBytes, 0, 4);

infoSize =
(((int)infoSizeBytes[3]&0xff)<<24) |
(((int)infoSizeBytes[2]&0xff)<<16) |
(((int)infoSizeBytes[1]&0xff)<<8) |
(int)infoSizeBytes[0]&0xff;

if(infoSize == 40) {
infoHeader = new byte[40];
infoHeader[0] = infoSizeBytes[0];
infoHeader[1] = infoSizeBytes[1];
infoHeader[2] = infoSizeBytes[2];
infoHeader[3] = infoSizeBytes[3];
inputStream.read(infoHeader, 4, 36);
}
else if(infoSize == 120) {
infoHeader = new byte[120];
infoHeader[0] = infoSizeBytes[0];
infoHeader[1] = infoSizeBytes[1];
infoHeader[2] = infoSizeBytes[2];
infoHeader[3] = infoSizeBytes[3];
inputStream.read(infoHeader, 4, 116);
}
else if(infoSize == 136) {
infoHeader = new byte[136];
infoHeader[0] = infoSizeBytes[0];
infoHeader[1] = infoSizeBytes[1];
infoHeader[2] = infoSizeBytes[2];
infoHeader[3] = infoSizeBytes[3];
inputStream.read(infoHeader, 4, 132);
}
else throw new Exception();

header = new InfoHeader(infoHeader);
System.out.println(header.toString());

}
}

/**
* <p>The InfoHeader class contains information
* about the dimensions and color format of a
* Windows Device Independant Bitmap.</p>
* <p>For Windows prior to Windows 95:
* Applications can use the BITMAPV4HEADER
* structure for added functionality.</p>
* <p>For Windows 95, Windows NT 4.0:
* Applications can use the BITMAPV4HEADER
* structure for added functionality.</p>
* <p>For Windows 98/Me, Windows 2000/XP:
* Applications can use the BITMAPV5HEADER
* structure for added functionality.</p>
*/
public class InfoHeader {

private final byte[] data;

/**
* The sole constructor for the InfoHeader class.
* @param b
*/
public InfoHeader(byte[] data) {
if( data.length == 40 ||
data.length == 120 ||
data.length != 136) {
this.data = data;
}
else
throw new IllegalArgumentException();
}

/**
*
* @return
*/
public InfoHeaderVersion getVersion() {
if(data.length == 40) {
return InfoHeaderVersion.V0;
}
else if(data.length == 120) {
return InfoHeaderVersion.V4;
}
else {
return InfoHeaderVersion.V5;
}
}

/**
* Specifies the number of bytes required by the structure.
* Applications should use this member to determine which
* bitmap information header structure is being used.
*
* @return
*/
public Long getSize() {
return null;
}

/**
* Specifies the width of the bitmap, in pixels.
*
* <p>If bV5Compression is BI_JPEG or BI_PNG,
* the bV5Width member specifies the width of the
* decompressed JPEG or PNG image in pixels.</p>
*
* @return
*/
public Long getWidth() {
return null;
}

/**
* Specifies the height of the bitmap, in pixels.
* If the value of bV5Height is positive, the bitmap is a
* bottom-up DIB and its origin is the lower-left corner.
* If bV5Height value is negative, the bitmap is a top-down
* DIB and its origin is the upper-left corner.
*
* <p>If bV5Height is negative, indicating a top-down DIB,
* bV5Compression must be either BI_RGB or BI_BITFIELDS.
* Top-down DIBs cannot be compressed.</p>
*
* <p>If bV5Compression is BI_JPEG or BI_PNG,
* the bV5Height member specifies the height of the
* decompressed JPEG or PNG image in pixels.</p>
*
* @return
*/
public Long getHeight() {
return null;
}

/**
* Specifies the number of planes for the target device.
* This value must be set to 1.
*
* @return
*/
public Integer getPlanes() {
return Integer.valueOf(1);
}

/**
* Specifies the number of bits that define each pixel
* and the maximum number of colors in the bitmap.
*
* @return
*/
public Integer getBitCount() {
return null;
}

/**
* Specifies that the bitmap is not compressed.
* The bV5RedMask, bV5GreenMask, and bV5BlueMask members
* specify the red, green, and blue components of each pixel.
* This is valid when used with 16- and 32-bpp bitmaps.
*
* @return
*/
public Compression getV5Compression() {
return null;
}

/**
* Specifies the size, in bytes, of the image.
* This may be set to zero for BI_RGB bitmaps.
*
* <p>If bV5Compression is BI_JPEG or BI_PNG,
* bV5SizeImage is the size of the JPEG or PNG image buffer.</p>
*
* @return
*/
public Long getSizeImage() {
return null;
}

/**
* Specifies the horizontal resolution, in pixels-per-meter,
* of the target device for the bitmap.
* An application can use this value to select a bitmap from
* a resource group that best matches the characteristics of
* the current device.
*
* @return
*/
public Integer getXPelsPerMeter() {
return null;
}

/**
* Specifies the vertical resolution, in pixels-per-meter,
* of the target device for the bitmap.
*
* @return
*/
public Integer getYPelsPerMeter() {
return null;
}

/**
* Specifies the number of color indexes in the color table
* that are actually used by the bitmap. If this value is
* zero, the bitmap uses the maximum number of colors
* corresponding to the value of the bV5BitCount member for
* the compression mode specified by bV5Compression.
*
* <p>If bV5ClrUsed is nonzero and bV5BitCount is less than
* 16, the bV5ClrUsed member specifies the actual number of
* colors the graphics engine or device driver accesses.
* If bV5BitCount is 16 or greater, the bV5ClrUsed member
* specifies the size of the color table used to optimize
* performance of the system color palettes.
* If bV5BitCount equals 16 or 32, the optimal color palette
* starts immediately following the BITMAPV5HEADER.
* If bV5ClrUsed is nonzero,
* the color table is used on palettized devices, and
* bV5ClrUsed specifies the number of entries.</p>
*
* @return
*/
public Integer getClrUsed() {
return null;
}

/**
* Specifies the number of color indexes that are
* required for displaying the bitmap.
* If this value is zero, all colors are required.
*
* @return
*/
public Integer getClrImportant() {
return null;
}

/**
* Color mask that specifies the red component of each pixel,
* valid only if bV5Compression is set to BI_BITFIELDS.
*
* @return
*/
public BitSet getRedMask() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Color mask that specifies the green component of each pixel,
* valid only if bV5Compression is set to BI_BITFIELDS.
*
* @return
*/
public BitSet getGreenMask() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Color mask that specifies the blue component of each pixel,
* valid only if bV5Compression is set to BI_BITFIELDS.
*
* @return
*/
public BitSet getBlueMask() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Color mask that specifies the alpha component of each pixel.
*
* @return
*/
public BitSet getAlphaMask() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Specifies the color space of the DIB.
*
* @return
*/
public LogicalColorSpace getCSType() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* A CIEXYZTRIPLE structure that specifies the x, y,
* and z coordinates of the three colors that correspond
* to the red, green, and blue endpoints for the logical
* color space associated with the bitmap.
* This member is ignored unless the bV5CSType member
* specifies LCS_CALIBRATED_RGB.
*
* @return
*/
public CIEXYZTriple getEndpoints() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Toned response curve for red.
* Used if bV5CSType is set to LCS_CALIBRATED_RGB.
* Specified in 16^16 format.
*
* @return
*/
public FixedPoint8Dot8 getGammaRed() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Toned response curve for green.
* Used if bV5CSType is set to LCS_CALIBRATED_RGB.
* Specified in 16^16 format.
*
* @return
*/
public FixedPoint8Dot8 getGammaGreen() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Toned response curve for blue.
* Used if bV5CSType is set to LCS_CALIBRATED_RGB.
* Specified in 16^16 format.
*
* @return
*/
public FixedPoint8Dot8 getGammaBlue() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Rendering intent for bitmap.
*
* @return
*/
public GamutMappingIntent getIntent() {
if(getVersion() == InfoHeaderVersion.V0 ||
getVersion() == InfoHeaderVersion.V4)
return null;
else
return null;
}

/**
* The offset, in bytes, from the beginning of the
* BITMAPV5HEADER structure to the start of the profile data.
* If the profile is embedded, profile data is the actual profile,
* and it is linked.
* (The profile data is the null-terminated file name of the profile.)
* This cannot be a Unicode string.
* It must be composed exclusively of characters from the
* Windows character set (code page 1252).
* These profile members are ignored unless the bV5CSType member
* specifies PROFILE_LINKED or PROFILE_EMBEDDED.
*
* @return
*/
public Long getProfileData() {
if(getVersion() == InfoHeaderVersion.V0 ||
getVersion() == InfoHeaderVersion.V4)
return null;
else
return null;
}

/**
* Size, in bytes, of embedded profile data.
*
* @return
*/
public Long getProfileSize() {
if(getVersion() == InfoHeaderVersion.V0 ||
getVersion() == InfoHeaderVersion.V4)
return null;
else
return null;
}

public String toString() {
return "TODO: implement InfoHeader.toString() method.\n" +
Arrays.toString(data);
}
}

/**
* The CIEXYZ class represents the x, y, and z coordinates
* of a specific color in a specified color space.
*
*/
public class CIEXYZ {

/**
* The x chromaticity value.
*/
private FixedPoint2Dot30 x;
/**
* The y chromaticity value.
*/
private FixedPoint2Dot30 y;
/**
* The z chromaticity value.
*/
private FixedPoint2Dot30 z;

/**
* @param value
* @return
*/
public static CIEXYZ valueOf(byte[] value) {
CIEXYZ ret = new CIEXYZ();
return ret;
}

/**
* @param value
* @return
*/
public static CIEXYZ valueOf(String value) {
CIEXYZ ret = new CIEXYZ();
return ret;
}

/**
* @return
*/
public byte[] write() {
byte[] ret = new byte[12];
return ret;
}

/**
*
*/
public String toString() {
return null;
}
}

/**
* The CIEXYZTRIPLE class represents the x, y, and z coordinates
* of the three colors that correspond to the red, green, and blue
* endpoints for a specified logical color space.
*/
public class CIEXYZTriple {

/**
* The xyz coordinates of the red endpoint.
*/
private CIEXYZ red;
/**
* The xyz coordinates of the green endpoint.
*/
private CIEXYZ green;
/**
* The xyz coordinates of the blue endpoint.
*/
private CIEXYZ blue;

/**
* @param value
* @return
*/
public static CIEXYZTriple valueOf(byte[] value) {
CIEXYZTriple ret = new CIEXYZTriple();
return ret;
}

/**
* @param value
* @return
*/
public static CIEXYZTriple valueOf(String value) {
CIEXYZTriple ret = new CIEXYZTriple();
return ret;
}

/**
* @return
*/
public byte[] write() {
byte[] ret = new byte[12];
return ret;
}

/**
* @return
*/
public String toString() {
return null;
}
}

/**
*
*/
public class FixedPoint2Dot30 {

/**
*
*/
private BigDecimal value =
BigDecimal.valueOf(0.0);

/**
* @param value
* @return
*/
public static FixedPoint2Dot30 valueOf(byte[] value) {
FixedPoint2Dot30 ret = new FixedPoint2Dot30();
return ret;
}

/**
* @param value
* @return
*/
public static FixedPoint2Dot30 valueOf(String value) {
FixedPoint2Dot30 ret = new FixedPoint2Dot30();
return ret;
}

/**
* @param value
* @return
*/
public static FixedPoint2Dot30 valueOf(BigDecimal value) {
FixedPoint2Dot30 ret = new FixedPoint2Dot30();
return ret;
}

/**
* @return
*/
public byte[] write() {
byte[] ret = new byte[4];
return ret;
}

/**
* @return
*/
public String toString() {
return null;
}
}

/**
*
*/
public class FixedPoint8Dot8 {

/**
*
*/
private BigDecimal value =
BigDecimal.valueOf(0.0);

/**
* @param value
* @return
*/
public static FixedPoint8Dot8 valueOf(byte[] value) {
FixedPoint8Dot8 ret = new FixedPoint8Dot8();
return ret;
}

/**
* @param value
* @return
*/
public static FixedPoint8Dot8 valueOf(String value) {
FixedPoint8Dot8 ret = new FixedPoint8Dot8();
return ret;
}

/**
* @param value
* @return
*/
public static FixedPoint8Dot8 valueOf(BigDecimal value) {
FixedPoint8Dot8 ret = new FixedPoint8Dot8();
return ret;
}

/**
* @return
*/
public byte[] write() {
byte[] ret = new byte[4];
return ret;
}

/**
* @return
*/
public String toString() {
return null;
}
}

/**
* Specifies the version of thid DIB header.
*/
public enum InfoHeaderVersion {

/**
* Equates to a
* <a
href="http://msdn2.microsoft.com/en-us/library/ms532290(VS.85).aspx">
* BITMAPINFOHEADER</a>
*/
V0,

/**
* Equates to a
* <a
href="http://msdn2.microsoft.com/en-us/library/ms532300(VS.85).aspx">
* BITMAPV4HEADER</a>
*/
V4,

/**
* Equates to a
* <a
href="http://msdn2.microsoft.com/en-us/library/ms532331(VS.85).aspx">
* BITMAPV5HEADER</a>
*/
V5;
}

/**
* Windows supports formats for compressing bitmaps that
* define their colors with 8 or 4 bits-per-pixel.
* Compression reduces the disk and memory storage
* required for the bitmap.
*/
public enum Compression
{
/**
* An uncompressed format.
*/
BI_RGB(0x0000),

/**
* A run-length encoded (RLE) format for bitmaps with 8 bpp.
* The compression format is a two-byte format consisting of
* a count byte followed by a byte containing a color index.
* If bV5Compression is BI_RGB and the bV5BitCount member is
* 16, 24, or 32, the bitmap array specifies the actual intensities
* of blue, green, and red rather than using color table indexes.
* For more information, see Bitmap Compression.
*/
BI_RLE8(0x0001),

/**
* An RLE format for bitmaps with 4 bpp.
* The compression format is a two-byte format consisting of a
* count byte followed by two word-length color indexes.
* For more information, see Bitmap Compression.
*/
BI_RLE4(0x0002),

/**
* Specifies that the bitmap is not compressed and that the
* color table consists of three DWORD color masks that specify the
* red, green, and blue components of each pixel.
* Valid when used with 16- and 32-bpp bitmaps.
*/
BI_BITFIELDS(0x0003),

/**
* Specifies that the image is compressed using the JPEG
* file Interchange Format.
* JPEG compression trades off compression against loss;
* it can achieve a compression ratio of 20:1 with little
* noticeable loss.
*/
BI_JPEG(0x0004),

/**
* Specifies that the image is compressed using the
* PNG file Interchange Format.
*/
BI_PNG(0x0005);

private int value;

private Compression(int value) {
this.value = value;
}
}

/**
* Specifies the relationship between
* logical and physical colors.
*/
public enum GamutMappingIntent
{
/**
* Maintains the white point.
* Matches the colors to their nearest
* color in the destination gamut.
*/
LCS_GM_ABS_COLORIMETRIC(0x00000008,
"Match", "Absolute Colorimetric"),

/**
* Maintains saturation.
* Used for business charts and other situations
* in which undithered colors are required.
*/
LCS_GM_BUSINESS(0x00000001, "Graphic", "Saturation"),

/**
* Maintains colorimetric match.
* Used for graphic designs and named colors.
*/
LCS_GM_GRAPHICS(0x00000002, "Proof",
"Relative Colorimetric"),

/**
* Maintains contrast.
* Used for photographs and natural images.
*/
LCS_GM_IMAGES(0x00000004, "Picture", "Perceptual");

private long value;
private String intent;
private String iccName;

/**
* @param value
* @param intent
* @param iccName
*/
private GamutMappingIntent(long value,
String intent, String iccName) {
this.value = value;
this.intent = intent;
this.iccName = iccName;
}

/**
* @return
*/
public long getValue() {
return value;
}

/**
* @return
*/
public String getIntent() {
return intent;
}

/**
* @return
*/
public String getICCName() {
return iccName;
}
}

/**
* Specifies where to find color profile information for this DIB.
*/
public enum LogicalColorSpace
{
/**
* Indicates that endpoints and
* gamma values are given in the appropriate fields.
*/
LCS_CALIBRATED_RGB(0x00000000),

/**
* Indicates that the bitmap is in sRGB color space.
*/
LCS_sRGB(0x73524742),

/**
* Indicates that the bitmap is in
* the system default color space, sRGB.
*/
LCS_WINDOWS_COLOR_SPACE(0x57696E20),

/**
* Indicates that bV5ProfileData points to the
* file name of the profile to use
* (gamma and endpoints values are ignored).
*/
LCS_PROFILE_LINKED(0x4C494E4B),

/**
* This value indicates that bV5ProfileData points to a
* memory buffer that contains the profile to be used
* (gamma and endpoints values are ignored).
*/
LCS_PROFILE_EMBEDDED(0x4D424544);

private long value;

private LogicalColorSpace(long value) {
this.value = value;
}
}
 
M

mmcclaf

I took a look at them but I'm still having troubles with a
FileInputStream, or perhaps its the understanding of how it works. And
then the trouble of trying to split it up into the different sections.
HAs anyone done anything like this with coding before?

There may be easier ways of getting the information you seek,
but just as a kick-start:

[TODO: needs work]

import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.BitSet;

public class BMPTest {

public static void main(String[] args)
throws Exception {

File file = new File(args[0]);
byte[] fileHeaderBytes = new byte[14];
byte[] infoSizeBytes = new byte[4];
int infoSize;
byte[] infoHeader;
InfoHeader header;

FileInputStream inputStream =
new FileInputStream(file);
inputStream.read(fileHeaderBytes);
inputStream.read(infoSizeBytes, 0, 4);

infoSize =
(((int)infoSizeBytes[3]&0xff)<<24) |
(((int)infoSizeBytes[2]&0xff)<<16) |
(((int)infoSizeBytes[1]&0xff)<<8) |
(int)infoSizeBytes[0]&0xff;

if(infoSize == 40) {
infoHeader = new byte[40];
infoHeader[0] = infoSizeBytes[0];
infoHeader[1] = infoSizeBytes[1];
infoHeader[2] = infoSizeBytes[2];
infoHeader[3] = infoSizeBytes[3];
inputStream.read(infoHeader, 4, 36);
}
else if(infoSize == 120) {
infoHeader = new byte[120];
infoHeader[0] = infoSizeBytes[0];
infoHeader[1] = infoSizeBytes[1];
infoHeader[2] = infoSizeBytes[2];
infoHeader[3] = infoSizeBytes[3];
inputStream.read(infoHeader, 4, 116);
}
else if(infoSize == 136) {
infoHeader = new byte[136];
infoHeader[0] = infoSizeBytes[0];
infoHeader[1] = infoSizeBytes[1];
infoHeader[2] = infoSizeBytes[2];
infoHeader[3] = infoSizeBytes[3];
inputStream.read(infoHeader, 4, 132);
}
else throw new Exception();

header = new InfoHeader(infoHeader);
System.out.println(header.toString());

}

}

/**
* <p>The InfoHeader class contains information
* about the dimensions and color format of a
* Windows Device Independant Bitmap.</p>
* <p>For Windows prior to Windows 95:
* Applications can use the BITMAPV4HEADER
* structure for added functionality.</p>
* <p>For Windows 95, Windows NT 4.0:
* Applications can use the BITMAPV4HEADER
* structure for added functionality.</p>
* <p>For Windows 98/Me, Windows 2000/XP:
* Applications can use the BITMAPV5HEADER
* structure for added functionality.</p>
*/
public class InfoHeader {

private final byte[] data;

/**
* The sole constructor for the InfoHeader class.
* @param b
*/
public InfoHeader(byte[] data) {
if( data.length == 40 ||
data.length == 120 ||
data.length != 136) {
this.data = data;
}
else
throw new IllegalArgumentException();
}

/**
*
* @return
*/
public InfoHeaderVersion getVersion() {
if(data.length == 40) {
return InfoHeaderVersion.V0;
}
else if(data.length == 120) {
return InfoHeaderVersion.V4;
}
else {
return InfoHeaderVersion.V5;
}
}

/**
* Specifies the number of bytes required by the structure.
* Applications should use this member to determine which
* bitmap information header structure is being used.
*
* @return
*/
public Long getSize() {
return null;
}

/**
* Specifies the width of the bitmap, in pixels.
*
* <p>If bV5Compression is BI_JPEG or BI_PNG,
* the bV5Width member specifies the width of the
* decompressed JPEG or PNG image in pixels.</p>
*
* @return
*/
public Long getWidth() {
return null;
}

/**
* Specifies the height of the bitmap, in pixels.
* If the value of bV5Height is positive, the bitmap is a
* bottom-up DIB and its origin is the lower-left corner.
* If bV5Height value is negative, the bitmap is a top-down
* DIB and its origin is the upper-left corner.
*
* <p>If bV5Height is negative, indicating a top-down DIB,
* bV5Compression must be either BI_RGB or BI_BITFIELDS.
* Top-down DIBs cannot be compressed.</p>
*
* <p>If bV5Compression is BI_JPEG or BI_PNG,
* the bV5Height member specifies the height of the
* decompressed JPEG or PNG image in pixels.</p>
*
* @return
*/
public Long getHeight() {
return null;
}

/**
* Specifies the number of planes for the target device.
* This value must be set to 1.
*
* @return
*/
public Integer getPlanes() {
return Integer.valueOf(1);
}

/**
* Specifies the number of bits that define each pixel
* and the maximum number of colors in the bitmap.
*
* @return
*/
public Integer getBitCount() {
return null;
}

/**
* Specifies that the bitmap is not compressed.
* The bV5RedMask, bV5GreenMask, and bV5BlueMask members
* specify the red, green, and blue components of each pixel.
* This is valid when used with 16- and 32-bpp bitmaps.
*
* @return
*/
public Compression getV5Compression() {
return null;
}

/**
* Specifies the size, in bytes, of the image.
* This may be set to zero for BI_RGB bitmaps.
*
* <p>If bV5Compression is BI_JPEG or BI_PNG,
* bV5SizeImage is the size of the JPEG or PNG image buffer.</p>
*
* @return
*/
public Long getSizeImage() {
return null;
}

/**
* Specifies the horizontal resolution, in pixels-per-meter,
* of the target device for the bitmap.
* An application can use this value to select a bitmap from
* a resource group that best matches the characteristics of
* the current device.
*
* @return
*/
public Integer getXPelsPerMeter() {
return null;
}

/**
* Specifies the vertical resolution, in pixels-per-meter,
* of the target device for the bitmap.
*
* @return
*/
public Integer getYPelsPerMeter() {
return null;
}

/**
* Specifies the number of color indexes in the color table
* that are actually used by the bitmap. If this value is
* zero, the bitmap uses the maximum number of colors
* corresponding to the value of the bV5BitCount member for
* the compression mode specified by bV5Compression.
*
* <p>If bV5ClrUsed is nonzero and bV5BitCount is less than
* 16, the bV5ClrUsed member specifies the actual number of
* colors the graphics engine or device driver accesses.
* If bV5BitCount is 16 or greater, the bV5ClrUsed member
* specifies the size of the color table used to optimize
* performance of the system color palettes.
* If bV5BitCount equals 16 or 32, the optimal color palette
* starts immediately following the BITMAPV5HEADER.
* If bV5ClrUsed is nonzero,
* the color table is used on palettized devices, and
* bV5ClrUsed specifies the number of entries.</p>
*
* @return
*/
public Integer getClrUsed() {
return null;
}

/**
* Specifies the number of color indexes that are
* required for displaying the bitmap.
* If this value is zero, all colors are required.
*
* @return
*/
public Integer getClrImportant() {
return null;
}

/**
* Color mask that specifies the red component of each pixel,
* valid only if bV5Compression is set to BI_BITFIELDS.
*
* @return
*/
public BitSet getRedMask() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Color mask that specifies the green component of each pixel,
* valid only if bV5Compression is set to BI_BITFIELDS.
*
* @return
*/
public BitSet getGreenMask() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Color mask that specifies the blue component of each pixel,
* valid only if bV5Compression is set to BI_BITFIELDS.
*
* @return
*/
public BitSet getBlueMask() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Color mask that specifies the alpha component of each pixel.
*
* @return
*/
public BitSet getAlphaMask() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Specifies the color space of the DIB.
*
* @return
*/
public LogicalColorSpace getCSType() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* A CIEXYZTRIPLE structure that specifies the x, y,
* and z coordinates of the three colors that correspond
* to the red, green, and blue endpoints for the logical
* color space associated with the bitmap.
* This member is ignored unless the bV5CSType member
* specifies LCS_CALIBRATED_RGB.
*
* @return
*/
public CIEXYZTriple getEndpoints() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Toned response curve for red.
* Used if bV5CSType is set to LCS_CALIBRATED_RGB.
* Specified in 16^16 format.
*
* @return
*/
public FixedPoint8Dot8 getGammaRed() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Toned response curve for green.
* Used if bV5CSType is set to LCS_CALIBRATED_RGB.
* Specified in 16^16 format.
*
* @return
*/
public FixedPoint8Dot8 getGammaGreen() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Toned response curve for blue.
* Used if bV5CSType is set to LCS_CALIBRATED_RGB.
* Specified in 16^16 format.
*
* @return
*/
public FixedPoint8Dot8 getGammaBlue() {
if(getVersion() == InfoHeaderVersion.V0)
return null;
else
return null;
}

/**
* Rendering intent for bitmap.
*
* @return...

read more »

Thanks everyone for your bits and pieces. Here is what I have so far
and yet still having troubles. I'm at the part now when I want to
output the contents of the colour table to the screen.

Here is class one:



import java.awt.*;
import java.io.*;
import java.awt.image.*;
public class CSE390Lab3BMPMcClafferty extends Component {
//--- Private constants
private final static int BITMAPFILEHEADER_SIZE = 14;
private final static int BITMAPINFOHEADER_SIZE = 40;
//--- Private variable declaration
//--- Bitmap file header
byte bitmapFileHeader [] = new byte [14];
byte bfType [] = {'B', 'M'};
int bfSize = 0;
int bfReserved1 = 0;
int bfReserved2 = 0;
int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
//--- Bitmap info header
byte bitmapInfoHeader [] = new byte [40];
int biSize = BITMAPINFOHEADER_SIZE;
int biWidth = 0;
int biHeight = 0;
int biPlanes = 1;
int biBitCount = 24;
int biCompression = 0;
int biSizeImage = 0x030000;
int biXPelsPerMeter = 0x0;
int biYPelsPerMeter = 0x0;
int biClrUsed = 0;
int biClrImportant = 0;
byte optionalPalette[];
byte imageData []= new byte [4];

//--- Bitmap raw data
private int bitmap [];
//--- File section
private FileOutputStream fo;
//--- Default constructor
public CSE390Lab3BMPMcClafferty() {}

public void displayFileHeader ()
{
System.out.println ("FILE HEADER");
System.out.println ("Type: " + bfType);
System.out.println ("Size: " + bfSize);
System.out.println ("Reserved 1: " + bfReserved1);
System.out.println ("Reserved 2: " + bfReserved2);
System.out.println ("Off Bits: " + bfOffBits);
}

public void displayInfoHeader ()
{
System.out.println ("INFO HEADER");
System.out.println ("Size of info header: " + biSize);
System.out.println ("Width: " + biWidth);
System.out.println ("Height: " + biHeight);
System.out.println ("Planes: " +biPlanes);
System.out.println ("Bit Count:" +biBitCount);
System.out.println ("Compression: "+ biCompression);
System.out.println ("Size: " + biSizeImage);
System.out.println ("Pixels per metre horizontally: " +
biXPelsPerMeter);
System.out.println ("Pixels per metre vertically: " +
biYPelsPerMeter);
System.out.println ("Number of colours used: " + biClrUsed);
System.out.println ("Important Colours: " + biClrImportant);
}

public void displayColourTable()
{
System.out.println ("Colour Table: ");
}

public void displayImageData(int row, int column, int height, int
width)
{

}

}





Class 2:
// The "CSE390Lab3McClafferty" class.


import java.io.*;
import java.lang.*;

public class CSE390Lab3McClafferty
{
public static int constructInt3 (byte[] in, int offset)
{

int ret = 0xff;

ret = (ret << 8) | ((int) in [offset + 2] & 0xff);

ret = (ret << 8) | ((int) in [offset + 1] & 0xff);

ret = (ret << 8) | ((int) in [offset + 0] & 0xff);

return (ret);

}


public static void main (String[] args)
{
CSE390Lab3BMPMcClafferty pic = new CSE390Lab3BMPMcClafferty
();
int nNumColors = 0;

try
{
File bmp = new File ("pic2.bmp");
FileInputStream bitStream = new FileInputStream (bmp);
bitStream.skip (2);
pic.bfSize = bitStream.read () + bitStream.read () * 256 +
bitStream.read () * 65536 + bitStream.read () * 16777216;
bitStream.skip (12);
pic.biWidth = bitStream.read () + bitStream.read () * 256
+ bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biHeight = bitStream.read () + bitStream.read () * 256
+ bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biPlanes = bitStream.read () + bitStream.read () *
256;
pic.biBitCount = bitStream.read () + bitStream.read () *
256;
pic.biCompression = bitStream.read () + bitStream.read ()
* 256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biSizeImage = bitStream.read () + bitStream.read () *
256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biXPelsPerMeter = bitStream.read () + bitStream.read
() * 256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biYPelsPerMeter = bitStream.read () + bitStream.read
() * 256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biClrUsed = bitStream.read () + bitStream.read () *
256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
nNumColors = pic.biClrUsed;
pic.biClrImportant = bitStream.read () + bitStream.read ()
* 256 + bitStream.read () * 65536 + bitStream.read () * 16777216;


if (pic.biClrUsed > 0)

{

nNumColors = pic.biClrUsed;

}

else

{

nNumColors = (1 & 0xff) << pic.biBitCount;

}

pic.optionalPalette = new byte [nNumColors * 4];
int npalette[] = new int [nNumColors];
// System.out.println("The number of Colors
is"+nNumColors);
bitStream.read (pic.optionalPalette, 0, nNumColors * 4);
int nindex8 = 0;
for (int n = 0 ; n < nNumColors ; n++)

{

npalette [n] = constructInt3 (pic.optionalPalette,
nindex8);
nindex8 += 4;

}
// Read the image data (actually indices into the palette)

// Scan lines are still padded out to even 4-byte

// boundaries.

int npad8 = (pic.biSizeImage / pic.biHeight) -
pic.biWidth;

// System.out.println("nPad is:"+npad8);



int ndata8[] = new int [pic.biWidth * pic.biHeight];

byte bdata[] = new byte [(pic.biWidth + npad8) *
pic.biHeight];

bitStream.read (bdata, 0, (pic.biWidth + npad8) *
pic.biHeight);

nindex8 = 0;

for (int j8 = 0 ; j8 < pic.biHeight ; j8++)
{
for (int i8 = 0 ; i8 < pic.biWidth ; i8++)
{
ndata8 [pic.biWidth * (pic.biHeight - j8 - 1) +
i8] = npalette [((int) bdata [nindex8] & 0xff)];
nindex8++;
}
nindex8 += npad8;
}
pic.displayFileHeader ();
pic.displayInfoHeader ();
pic.displayColourTable ();
//pic.optionalPalette = bitStream.read () + bitStream.read
() * 256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
/*bitStream.skip (28);
int index = bmp.toString ().lastIndexOf ("bmp");
String dFileName = bmp.toString ().substring (0, index) +
"txt";

File destFile = new File (dFileName);
FileOutputStream ostream = new FileOutputStream
(destFile);

ostream.write (new String
("{rtf1ansiansicpg1252deff0{fonttbl{f0fnilfcharset0 Courier New;}
{f1fmodernfprq1fcharset0 Courier New;}}").getBytes ());
ostream.write (0x0d);
ostream.write (0x0a);

ostream.write (new String ("{colortbl ;").getBytes ());

int red, green, blue, count = 0, dcount = 255;
for (int i = 0 ; i < 256 ; i++)
{
blue = bitStream.read ();
green = bitStream.read ();
red = bitStream.read ();
ostream.write (new String ("red" + red + "green" +
green + "blue" + blue + ";").getBytes ());
bitStream.read ();
}

ostream.write (new String ("}").getBytes ());
ostream.write (0x0d);
ostream.write (0x0a);
ostream.write (new String ("viewkind4uc1pardlang1033f0fs20
").getBytes ());

char ch[] = {'!', '#', '$', '%', '&', '*', '+', '0', '?',
'@',
'§', '¥', '¤', '£', '¢', 'µ', '¶', 'ß', '>', '<',
'ª'};

int temp, colorCode = -1;

int orgWidth = width;

if (width % 4 != 0)
width = width + 4 - (width % 4);
byte allBytes[] = new byte [height * width];
bitStream.read (allBytes);

for (int j = height - 1 ; j >= 0 ; j--)
{
for (int i = 0 ; i < orgWidth ; i++)
{
temp = allBytes [(j * width) + i];

if (temp < 0)
{
temp *= -1;
temp = 128 + 128 - temp;
}

temp += 1;
if (colorCode != temp)
ostream.write (new String ("cf" + (temp) + "
").getBytes ());
ostream.write (ch [temp % 21]);
colorCode = temp;
}
ostream.write (new String ("par").getBytes ());
ostream.write (0x0d);
ostream.write (0x0a);
}
*/
}
catch (Exception e)
{
System.out.println ("Exception Thrown: " + e);
}

} // main method


// build an int from a byte array - convert little to big endian

// set high order bytes to 0xfff


} // CSE390Lab3McClafferty class


But I'm kind of lost as to how to even output the colourtable to screen
 
J

Jeff Higgins

(e-mail address removed) wrote:
(e-mail address removed) wrote:

But I'm kind of lost as to how to even output the colourtable to screen

I get:
java.lang.OutOfMemoryError: Java heap space
at this line:
pic.optionalPalette = new byte[nNumColors * 4];
using this bitmap file:
<http://preview.tinyurl.com/5263tj>.

The value of nNumColors is: 16777216
at the point of failure.

Is pic.optionalPalette you're "colourtable"?

I haven't had time to look any more just yet.

JH
 
M

mmcclaf

Thats what I think it is. I mean for this next part that I'm supposed
to do, I'm supposed to output the contents of the colour table to the
screen. So of course, I'm using the palette to find out the colours
and how many there are. But I don't even know how to do this part
correctly. I mean, sure I'm looking at code (http://www.lordjoe.com/
JavaCourse/BMPLoader.html) and trying to follow it, but I'm completely
lost at this part of the code as to how to even read it in.
 
J

Jeff Higgins

Jeff Higgins said:
(e-mail address removed) wrote:
(e-mail address removed) wrote:

But I'm kind of lost as to how to even output the colourtable to screen

I get:
java.lang.OutOfMemoryError: Java heap space
at this line:
pic.optionalPalette = new byte[nNumColors * 4];
using this bitmap file:
<http://preview.tinyurl.com/5263tj>.

The value of nNumColors is: 16777216
at the point of failure.

Is pic.optionalPalette you're "colourtable"?

I haven't had time to look any more just yet.

JH

public class CSE390Lab3McClafferty {

public static int constructInt3(byte[] in, int offset) {

int ret = 0xff;

ret = (ret << 8) | ((int) in[offset + 2] & 0xff);

ret = (ret << 8) | ((int) in[offset + 1] & 0xff);

ret = (ret << 8) | ((int) in[offset + 0] & 0xff);

return (ret);

}

public static void main(String[] args) {

CSE390Lab3BMPMcClafferty pic =
new CSE390Lab3BMPMcClafferty();
int nNumColors = 0;

try {
File bmp = new File("c://temp//FLAG_B24.BMP");
FileInputStream bitStream = new FileInputStream(bmp);
bitStream.skip(2);
pic.bfSize = bitStream.read() +
bitStream.read() * 256 +
bitStream.read() * 65536 +
bitStream.read() * 16777216;
bitStream.skip(12);
pic.biWidth = bitStream.read() +
bitStream.read() * 256 +
bitStream.read() * 65536 +
bitStream.read() * 16777216;
pic.biHeight = bitStream.read() +
bitStream.read() * 256 +
bitStream.read() * 65536 +
bitStream.read() * 16777216;
pic.biPlanes = bitStream.read() +
bitStream.read() * 256;
pic.biBitCount = bitStream.read() +
bitStream.read() * 256;
pic.biCompression = bitStream.read() +
bitStream.read() * 256 +
bitStream.read() * 65536 +
bitStream.read() * 16777216;
pic.biSizeImage = bitStream.read() +
bitStream.read() * 256 +
bitStream.read() * 65536 +
bitStream.read() * 16777216;
pic.biXPelsPerMeter = bitStream.read() +
bitStream.read() * 256 +
bitStream.read() * 65536 +
bitStream.read() * 16777216;
pic.biYPelsPerMeter = bitStream.read() +
bitStream.read() * 256 +
bitStream.read() * 65536 +
bitStream.read() * 16777216;
pic.biClrUsed = bitStream.read() +
bitStream.read() * 256 +
bitStream.read() * 65536 +
bitStream.read() * 16777216;
nNumColors = pic.biClrUsed;
pic.biClrImportant = bitStream.read() +
bitStream.read() * 256 +
bitStream.read() * 65536 +
bitStream.read() * 16777216;

// biClrUsed: Specifies the number of color indexes in the
// color table that are actually used by the bitmap.

// If this value is zero, the bitmap uses the maximum number
// of colors corresponding to the value of the biBitCount member
// for the compression mode specified by biCompression.

// If biClrUsed is nonzero and the biBitCount member is less than 16,
// the biClrUsed member specifies the actual number of colors the
// graphics engine or device driver accesses.

// If biBitCount is 16 or greater, the biClrUsed member specifies
// the size of the color table used to optimize performance of the
// system color palettes.

// If biBitCount equals 16 or 32, the optimal color palette starts
// immediately following the three DWORD masks.

// When the bitmap array immediately follows the BITMAPINFO structure,
// it is a packed bitmap. Packed bitmaps are referenced by a single
pointer.

// Packed bitmaps require that the biClrUsed member must be either
zero or
// the actual size of the color table.


if (pic.biClrUsed > 0) {
nNumColors = pic.biClrUsed;
}
else {
nNumColors = (1 & 0xff) << pic.biBitCount;
}

pic.optionalPalette = new byte[nNumColors * 4];
int npalette[] = new int[nNumColors];
// System.out.println("The number of Colors is"+ nNumColors);
bitStream.read(pic.optionalPalette, 0, nNumColors * 4);
int nindex8 = 0;
for (int n = 0; n < nNumColors; n++) {
npalette[n] = constructInt3(pic.optionalPalette, nindex8);
nindex8 += 4;
}

// [SNIP]

} catch (Exception e) {
System.out.println("Exception Thrown: " + e);
}

} // main method

}
 
J

Jeff Higgins

Thats what I think it is. I mean for this next part that I'm supposed
to do, I'm supposed to output the contents of the colour table to the
screen. So of course, I'm using the palette to find out the colours
and how many there are. But I don't even know how to do this part
correctly. I mean, sure I'm looking at code (http://www.lordjoe.com/
JavaCourse/BMPLoader.html) and trying to follow it, but I'm completely
lost at this part of the code as to how to even read it in.

I'm sure that lordjoe is fine, without even looking, and following
code examples is fine, but have you looked into the horse's mouth?
<http://msdn2.microsoft.com/en-us/library/ms532349(VS.85).aspx>
There's a lot there, look for "Bitmap Storage", BITMAPINFOHEADER,
etc. etc.
 
M

mmcclaf

I have looked at the coding, but still lost as to what I'm trying to
do. I understand/did the header and the file info stuff.

When I say lost, I mean even trying to get receive the colour table,
then format it so it looks like : 124.024.232.000 would be an an
example of one pixel
 
M

mmcclaf

Good news, I managed to get the next part to half work but I don't
think I'm getting the right bytes in for my colours.

// The "CSE390Lab3McClafferty" class.


import java.io.*;
import java.lang.*;
import java.text.*;

public class CSE390Lab3McClafferty
{
public static void main (String[] args)
{
CSE390Lab3BMPMcClafferty pic = new CSE390Lab3BMPMcClafferty
();
int nNumColors = 0;
int count = 0;
int indexer=0;

try
{
File bmp = new File ("pic1.bmp");
FileInputStream bitStream = new FileInputStream (bmp);
bitStream.skip (2);
pic.bfSize = bitStream.read () + bitStream.read () * 256 +
bitStream.read () * 65536 + bitStream.read () * 16777216;
bitStream.skip (12);
pic.biWidth = bitStream.read () + bitStream.read () * 256
+ bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biHeight = bitStream.read () + bitStream.read () * 256
+ bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biPlanes = bitStream.read () + bitStream.read () *
256;
pic.biBitCount = bitStream.read () + bitStream.read () *
256;
pic.biCompression = bitStream.read () + bitStream.read ()
* 256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biSizeImage = bitStream.read () + bitStream.read () *
256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biXPelsPerMeter = bitStream.read () + bitStream.read
() * 256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biYPelsPerMeter = bitStream.read () + bitStream.read
() * 256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
pic.biClrUsed = bitStream.read () + bitStream.read () *
256 + bitStream.read () * 65536 + bitStream.read () * 16777216;
nNumColors = pic.biClrUsed;
pic.biClrImportant = bitStream.read () + bitStream.read ()
* 256 + bitStream.read () * 65536 + bitStream.read () * 16777216;



byte[] byBuf = new byte [4];
int i = bitStream.read (byBuf);
System.out.println (i);
NumberFormat formatter = new DecimalFormat ("000");
String index=formatter.format (indexer);
System.out.print(index + " ");
while ((i = bitStream.read (byBuf)) != -1)
{
if (i != 4)
throw new IOException ("Unexpected end of binary
data! bitmap is corrupted");

int iRed = byBuf [0];
int iGreen = byBuf [1];
int iBlue = byBuf [2];
int iUnused = byBuf [3];

String dRed = formatter.format (iRed);
String dGreen = formatter.format (iGreen);
String dBlue = formatter.format (iBlue);
String dUnused = formatter.format (iUnused);
String oDisplay = dRed + "." + dGreen + "." + dBlue +
"." + dUnused + " ";
count++;
if (count == 5)
{
System.out.println ("\n");
count =0;
indexer++;
index=formatter.format (indexer);
System.out.print (index + " ");
}


System.out.print (oDisplay);
}



pic.displayFileHeader ();
pic.displayInfoHeader ();
pic.displayColourTable ();

}
catch (Exception e)
{
System.out.println ("Exception Thrown: " + e);
}

} // main method


// build an int from a byte array - convert little to big endian

// set high order bytes to 0xfff


} // CSE390Lab3McClafferty class




Any ideas?
 
J

Jeff Higgins

mmcclaf said:
Good news, I managed to get the next part to half work but I don't
think I'm getting the right bytes in for my colours.
Any ideas?

Yes, a couple.

It seems to me that you may be
trying to do too many tasks at one time.

Have you determined that your bitmap
contains a color palette?

Have you determined the number of it's entries?

Have you retrieved the array of bytes
that represents the color palette?

Are you having trouble translating the
color palette bytes into a form that you can use?

import java.util.HashMap;
import java.util.Map;

public class TranslateColorData {

public static void main(String[] args) {

// Given byte[] palette, and Map colorNames,
// produce the table as commented below.

byte[] palette =
{ 0,0,0,0,-1,-1,-1,0,
-64,-64,-64,0,-128,-128,-128,0,
-1,0,0,0,-128,0,0,0,
0,-1,0,0,0,-128,0,0,
0,0,-1,0,0,0,-128,0,
-1,0,-1,0,-128,0,-128,0,
0,-1,-1,0,0,-128,-128,0,
-1,-1,0,0,-128,-128,0,0
};

Map<Integer, String> colorNames =
new HashMap<Integer, String>();
colorNames.put(Integer.valueOf(0), "Black");
colorNames.put(Integer.valueOf(16777215), "White");
colorNames.put(Integer.valueOf(12632256), "Gray");
colorNames.put(Integer.valueOf(8421504), "Dark Grey");
colorNames.put(Integer.valueOf(255), "Red");
colorNames.put(Integer.valueOf(128), "Dark Red");
colorNames.put(Integer.valueOf(65280), "Green");
colorNames.put(Integer.valueOf(32768), "Dark Green");
colorNames.put(Integer.valueOf(16711680), "Blue");
colorNames.put(Integer.valueOf(8388608), "Dark Blue");
colorNames.put(Integer.valueOf(16711935), "Magenta");
colorNames.put(Integer.valueOf(8388736), "Dark Magenta");
colorNames.put(Integer.valueOf(16776960), "Cyan");
colorNames.put(Integer.valueOf(8421376), "Dark Cyan");
colorNames.put(Integer.valueOf(65535), "Yellow");
colorNames.put(Integer.valueOf(32896), "Brown");

/*
Black {0 0 0} {0}
White {255 255 255} {16777215}
Gray {192 192 192} {12632256}
Dark Grey {128 128 128} {8421504}
Red {255 0 0} {255}
Dark Red {128 0 0} {128}
Green {0 255 0} {65280}
Dark Green {0 128 0} {32768}
Blue {0 0 255} {16711680}
Dark Blue {0 0 128} {8388608}
Magenta {255 0 255} {16711935}
Dark Magenta {128 0 128} {8388736}
Cyan {0 255 255} {16776960}
Dark Cyan {0 128 128} {8421376}
Yellow {255 255 0} {65535}
Brown {128 128 0} {32896}
*/
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,160
Latest member
CollinStri
Top