#include <stdio.h>
#include <stdlib.h>

#include "opd_jp2.h"
#include "main.h"

/**
 *
 * int readBitmap(FILE *infile, j2k_image_t **image)
 *
 * This function reads a Windows Bitmap from an open file.
 *
 */
int readBitmap(FILE *infile, opd_image_t *image) {
	int	MagicNumber;
	int bfsize;
	int bfReserved1;
	int bfReserved2;
	int bfOffBits;
	int biSize;
	int biWidth;
	int biHeight;
	int biPlanes;
	int biBitCount;
	int biCompression;
	int biSizeImage;
	int biXPelsPerMeter;
	int biYPelsPerMeter;
	int biClrUsed;
	int biClrImportant;
	int c,i,y,x;
	int palette_r[256];
	int palette_g[256];
	int palette_b[256];
	int isGray			= FALSE;
	int bytesPerRow;
	int channels;
	int componentSize;

	/* for the image structure */
	unsigned char	*pucRawData;
	int				iDx,iDy,iDc;
	unsigned int	uiDataOffset;

	/* Check the input parameters */
	if (infile != NULL) {
		/* read the Magic Number */
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);
		MagicNumber  = c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);
		MagicNumber |= c;

		/* check whether the Magic Number is correct */
		if (MagicNumber != (('B' << 8) | ('M'))) return(OPD_ERROR_FILE_CORRUPT);

		/* read the Bitmapfileheader */
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfsize		 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfsize		|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfsize		|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfsize		|= c << 24;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfReserved1  = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfReserved1 |= c << 8;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfReserved2  = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfReserved2 |= c << 8;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfOffBits	 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfOffBits	|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfOffBits	|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		bfOffBits	|= c << 24;

		/* read the Bitmapinfoheader */
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biSize		 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biSize		|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biSize		|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biSize		|= c << 24;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biWidth		 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biWidth		|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biWidth		|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biWidth		|= c << 24;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biHeight	 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biHeight	|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biHeight	|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biHeight	|= c << 24;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biPlanes	 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biPlanes	|= c << 8;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biBitCount	 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biBitCount	|= c << 8;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biCompression	 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biCompression	|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biCompression	|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biCompression	|= c << 24;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biSizeImage	 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biSizeImage	|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biSizeImage	|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biSizeImage	|= c << 24;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biXPelsPerMeter	 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biXPelsPerMeter	|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biXPelsPerMeter	|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biXPelsPerMeter	|= c << 24;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biYPelsPerMeter	 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biYPelsPerMeter	|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biYPelsPerMeter	|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biYPelsPerMeter	|= c << 24;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biClrUsed	 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biClrUsed	|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biClrUsed	|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biClrUsed	|= c << 24;

		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biClrImportant	 = c;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biClrImportant	|= c << 8;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biClrImportant	|= c << 16;
		if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);		biClrImportant	|= c << 24;

		/* check whether a palettized image. read a palette and check whether
		 * the image is possibly gray */
		if (biBitCount == 8) {
			isGray = TRUE;

			/* read the palette */
			for (i = 0; i < 256; i++) {
				if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);	palette_b[i] = c;
				if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);	palette_g[i] = c;
				if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);	palette_r[i] = c;
				if ((c = fgetc(infile)) == -1) return(OPD_ERROR_FILE_CORRUPT);	/* reserved value */
				/* palette still gray ? */
				if (palette_r[i] != palette_g[i]) isGray = FALSE;
				if (palette_r[i] != palette_b[i]) isGray = FALSE;
			}

			/* depending whether the image is gray or colored,
			 * the image structure is allocated */
			if (isGray == TRUE) {
				bytesPerRow		= (biWidth + 3) & ~0x3;
				componentSize	= biHeight * bytesPerRow;
				channels		= 1;
				if ((pucRawData = (unsigned char*)(opd_jp2_alloc(componentSize))) == NULL) {
					return(OPD_ERROR_NO_MEMORY);
				}

				if (fread(pucRawData,1,componentSize,infile) != componentSize) {
					opd_jp2_free(pucRawData);
					return(OPD_ERROR_FILE_CORRUPT);
				}

				uiDataOffset	= (biHeight - 1) * bytesPerRow;;
				iDx				= 1;
				iDy				= -bytesPerRow;
				iDc				= 0;

			} else { // not gray, palettized images not supported
				bytesPerRow		= biWidth	* 3;
				componentSize	= biHeight	* bytesPerRow;
				channels		= 3;
				if ((pucRawData = (unsigned char*)(opd_jp2_alloc(componentSize))) == NULL) {
					return(OPD_ERROR_NO_MEMORY);
				}
				
				for (y = 0; y < biHeight; y++) {
					for (x = 0; x < biWidth; x++) {
						if ((c = fgetc(infile)) == -1) {
							free(pucRawData);
							return(OPD_ERROR_FILE_CORRUPT);
						}
						pucRawData[(y * biWidth + x) * 3 + 0] = palette_b[c];
						pucRawData[(y * biWidth + x) * 3 + 1] = palette_g[c];
						pucRawData[(y * biWidth + x) * 3 + 2] = palette_r[c];
					}
					
					while(x < ((biWidth + 3) & ~0x3)) {
						if ((c = fgetc(infile)) == -1) {
							free(pucRawData);
							return(OPD_ERROR_FILE_CORRUPT);
						}
					}
				}
				uiDataOffset	= (biHeight - 1) * bytesPerRow + (channels - 1);
				iDx				= 3;
				iDy				= -bytesPerRow;
				iDc				= -1;
			} /* end bracket <-- if (isGray == TRUE) else */
			/* allocate the components structure */
		} else if (biBitCount == 24) {
			/* this is a normal rgb image without any palette */
			bytesPerRow		= ((biWidth * 3) + 3) & ~0x3;
			componentSize	= biHeight * bytesPerRow;
			channels		= 3;

			if ((pucRawData = (unsigned char*)(opd_jp2_alloc(componentSize))) == NULL) {
				return(OPD_ERROR_NO_MEMORY);
			}

			if (fread(pucRawData,1,componentSize,infile) != componentSize) {
				opd_jp2_free(pucRawData);
				return(OPD_ERROR_FILE_CORRUPT);
			}
			uiDataOffset	= (biHeight - 1) * bytesPerRow + (channels - 1);
			iDx				= 3;
			iDy				= -bytesPerRow;
			iDc				= -1;
		} /* end bracket <-- if (biBitCount == 24) */

		/* we have the image data read. fill out the return values */
		if (image != NULL) {
			/* set the components in the image structure */
			image -> uiChannels	= channels;

			/* The interleaved variant is not used */
			image -> pucData		= pucRawData;
			image -> uiDataOffset	= uiDataOffset;
			image -> iDx			= iDx;
			image -> iDy			= iDy;
			image -> iDc			= iDc;
			image -> iPrecision		= 8;
			image -> uiWidth		= biWidth;
			image -> uiHeight		= biHeight;
			image -> uiChannels		= channels;

			/* everything was ok, return success */
			return(OPD_ERROR_OK);
		} else {
			return(OPD_ERROR_NO_MEMORY);
		}

	} /* end bracket <-- if (infile != NULL) */
	return(OPD_ERROR_FILE_CORRUPT);
}

int writeBitmap(FILE *outfile, opd_image_t *image) {
	int	MagicNumber;
	int bfsize;
	int bfReserved1;
	int bfReserved2;
	int bfOffBits;
	int biSize;
	int biWidth;
	int biHeight;
	int biPlanes;
	int biBitCount;
	int biCompression;
	int biSizeImage;
	int biXPelsPerMeter;
	int biYPelsPerMeter;
	int biClrUsed;
	int biClrImportant;
	int i;
	int palette_r[256];
	int palette_g[256];
	int palette_b[256];

	int		len = 0;
	int		rowsize,imagesize,y,x;

	if ((outfile == NULL) || (image == NULL)) return(OPD_ERROR_BAD_PARAMETER);

	/* fill out the known values */
	MagicNumber		= (('B' << 8) | ('M'));
	bfsize			= 14 + 40 + (image -> uiChannels == 1 ? 1024 : 0);	/* bitmapfileheader + bitmapinfoheader */
	bfReserved1		= 0;
	bfReserved2		= 0;
	bfOffBits		= 14 + 40 + (image -> uiChannels == 1 ? 1024 : 0);

	biSize			= 40;		/* sizeof(bitmapinfoheader) */
	biWidth			= image->uiWidth;//(image -> x1) - (image -> x0);
	biHeight		= image->uiHeight;//(image -> y1) - (image -> y0);
	biPlanes		= 1;
	biCompression	= 0; /* BI_RGB */
	biSizeImage		= 0; /* for uncompressed images this can be 0 */
	biXPelsPerMeter	= 0x1710;
	biYPelsPerMeter	= 0x1710;
	biClrUsed		= 0;
	biClrImportant	= 0;

	/* check whether all components have the same size */
	switch(image -> uiChannels) {
	case 1:
		/* check the precision and whether the image is signed */
		if (image -> iPrecision != 8) return(OPD_ERROR_UNSUPPORTED);

		rowsize		= (biWidth + 3) & ~0x3;
		imagesize	= rowsize * biHeight;
		bfsize	   += imagesize + 1024; /* plus palette */
		/* we need also an image palette */
		for (i = 0; i < 256; i++) palette_r[i] = palette_g[i] = palette_b[i] = i;
		biBitCount	= 8;
		break;
	case 3:
		/* check that the precision is ok */
		if (image -> iPrecision != 8) return(OPD_ERROR_UNSUPPORTED);
		rowsize		= (biWidth * 3 + 3) & ~0x3;
		imagesize	= rowsize * biHeight;
		bfsize	   += imagesize;
		biBitCount	= 24;
		break;
	default:
		return(OPD_ERROR_UNSUPPORTED);
	}

	/* Write the header */
	if (fputc(((MagicNumber     >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( MagicNumber            & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( bfsize                 & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((bfsize          >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((bfsize          >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((bfsize          >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( bfReserved1            & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((bfReserved1     >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( bfReserved2            & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((bfReserved2     >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( bfOffBits              & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((bfOffBits       >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((bfOffBits       >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((bfOffBits       >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biSize                 & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biSize          >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biSize          >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biSize          >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biWidth                & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biWidth         >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biWidth         >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biWidth         >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biHeight               & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biHeight        >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biHeight        >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biHeight        >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biPlanes               & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biPlanes        >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biBitCount             & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biBitCount      >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biCompression          & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biCompression   >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biCompression   >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biCompression   >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biSizeImage            & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biSizeImage     >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biSizeImage     >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biSizeImage     >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biXPelsPerMeter        & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biXPelsPerMeter >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biXPelsPerMeter >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biXPelsPerMeter >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biYPelsPerMeter        & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biYPelsPerMeter >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biYPelsPerMeter >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biYPelsPerMeter >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biClrUsed              & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biClrUsed       >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biClrUsed       >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biClrUsed       >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(( biClrImportant         & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biClrImportant  >> 8 ) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biClrImportant  >> 16) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
	if (fputc(((biClrImportant  >> 24) & 0xFF),outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);

	if (biBitCount == 8) {
		for (i = 0; i < 256; i++) {
			if (fputc(palette_r[i],outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
			if (fputc(palette_g[i],outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
			if (fputc(palette_b[i],outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
			if (fputc(0,outfile)            == EOF) return(OPD_ERROR_FILE_CORRUPT);
		}

		for (y = biHeight - 1; y >= 0; y--) {
			for (x = i = 0; x < biWidth; x++, i++) {
				if (fputc(image -> pucData[image -> uiDataOffset + y * image -> iDy + x * image -> iDx],outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
			}
			for (; i < rowsize; i++) if (fputc(0,outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
		}
	} else {
		for (y = biHeight - 1; y >= 0; y--) {
			for (x = i = 0; x < biWidth; x++, i+=3) {
				if (fputc(image -> pucData[image -> uiDataOffset + y * image -> iDy  + x * image -> iDx + 2 * image -> iDc],outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
				if (fputc(image -> pucData[image -> uiDataOffset + y * image -> iDy  + x * image -> iDx + 1 * image -> iDc],outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
				if (fputc(image -> pucData[image -> uiDataOffset + y * image -> iDy  + x * image -> iDx + 0 * image -> iDc],outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
			}
			for (; i < rowsize; i++) if (fputc(0,outfile) == EOF) return(OPD_ERROR_FILE_CORRUPT);
		}
	}
	return(OPD_ERROR_OK);
}
