Ejemplo n.º 1
0
	bool InternalGenerator::writeText (const Byte *string)
	{
	#ifdef DEBUG_INTERNALGENERATOR
//		m_device->debug ("!!!! InternalGenerator: writeText> ", (const char *) string);
	#endif

		DWord length = DWord (strlen ((const char *) string));

		if (!m_device->writeInternal (string, length)) return false;

		return true;
	}
Ejemplo n.º 2
0
	bool Image::writeToDevice (void)
	{
	CHECK_DEVICE;

	#ifdef DEBUG_IMAGE
		m_device->debug ("\n>>>> Image::writeToDevice <<<<\n");
	#endif

	#ifdef DEBUG_IMAGE
		Dump (mappingMode);
		//Dump (MFP_width);	// will change below
		//Dump (MFP_height);
		Dump (MFP_unknown);

		Dump (indent);
		//Dump (width);
		//Dump (height);
		Dump (zero);

		Dump (numHeaderBytes);
		//Dump (numDataBytes);
		//Dump (horizontalScalingRel1000);
		//Dump (verticalScalingRel1000);
	#endif

		// sanity checking
		if (!m_externalImage || m_externalImageSize <= 0 ||
				m_originalWidth <= 0 || m_originalHeight <= 0 ||
				m_displayedWidth <= 0 || m_displayedHeight <= 0)
		{
			ErrorAndQuit (Error::InternalError, "uninitialised or invalid Image\n");
		}

		//
		// write data
		//
		//
		if (getIsWMF ())
		{
			// Header check
			WMFHeader wmfHeader;
			m_device->setCache (m_externalImage);
				wmfHeader.setDevice (m_device);
				if (!wmfHeader.readFromDevice ()) return false;

				// TODO: fix this incorrect check (see wmf.cpp)
				//if (wmfHeader.getFileSize () * sizeof (Word) != m_externalImageSize)
				//	m_device->error (Error::Warn, "wmfHeader.fileSize != externalImageSize\n");
			m_device->setCache (NULL);


			//
			// set image dimensions
			//

			// entire BitmapHeader is unused with WMFs
			m_bmh->setWidth (0);
			m_bmh->setHeight (0);
			m_bmh->setWidthBytes (0);
			m_bmh->setNumPlanes (0);
			m_bmh->setBitsPerPixel (0);

			m_MFP_width = Word (Twip2Milli (m_originalWidth * 0.75) * 100.0);
			m_MFP_height = Word (Twip2Milli (m_originalHeight * 0.75) * 100.0);

			m_width = Word (m_displayedWidth);
			m_height = Word (m_displayedHeight);

			// not used by WMFs
			m_horizontalScalingRel1000 = m_verticalScalingRel1000 = 1000;


			// write header
			setNumDataBytes (m_externalImageSize);
			if (!ImageGenerated::writeToDevice ())
				return false;

			// external=internal with WMF (i.e. we really do write a WMF)
			if (!m_device->writeInternal (m_externalImage, m_externalImageSize)) return false;
		}
		else	//	if (getIsBMP ())
		{
			m_device->setCache (m_externalImage);

			BMP_BitmapFileHeader fileHeader;
			fileHeader.setDevice (m_device);
			if (!fileHeader.readFromDevice ()) return false;


			/*Word colorTableSize = (1 << m_bmh->getNumPlanes ()) * BMP_BitmapColorIndex::s_size;

			// fileHeader
			DWord fileSize = BMP_BitmapFileHeader::s_size + BMP_BitmapInfoHeader::s_size
												+ colorTableSize
												+ (m_bmh->getHeight ()
													* getBytesPerScanLine (m_bmh->getWidth (), m_bmh->getBitsPerPixel (), 4));

			fileHeader.setTotalBytes (fileSize);
			fileHeader.setActualImageOffset (BMP_BitmapFileHeader::s_size + BMP_BitmapInfoHeader::s_size
														+ colorTableSize);*/

			// infoHeader
			BMP_BitmapInfoHeader infoHeader;
			infoHeader.setDevice (m_device);
			if (!infoHeader.readFromDevice ()) return false;

			// write out each scanline
			// to .WRI (padded to 2) vs input BMP (padded to 4
			Word scanLineWRILength = getBytesPerScanLine (infoHeader.getWidth (), infoHeader.getBitsPerPixel (), 2);
			Word scanLineBMPLength = getBytesPerScanLine (infoHeader.getWidth (), infoHeader.getBitsPerPixel (), 4);

			if (infoHeader.getWidth () <= 0 || infoHeader.getHeight () <= 0)
				ErrorAndQuit (Error::InvalidFormat, "infoHeader invalid dimensions\n");

			// did the user lie about the dimensions of the BMP?
			if (infoHeader.getWidth () != Word (Twip2Point (m_originalWidth)))
				m_device->error (Error::Warn, "infoHeader width != m_originalWidth\n");
			if (infoHeader.getHeight () != Word (Twip2Point (m_originalHeight)))
				m_device->error (Error::Warn, "infoHeader.height != m_originalHeight\n");

			m_bmh->setWidth (infoHeader.getWidth ());
			m_bmh->setHeight (infoHeader.getHeight ());
			m_bmh->setWidthBytes (scanLineWRILength);
			if (infoHeader.getNumPlanes () != 1)
				ErrorAndQuit (Error::InvalidFormat, "infoHeader.getNumPlanes() != 1\n");
			m_bmh->setNumPlanes (infoHeader.getNumPlanes ());
			m_bmh->setBitsPerPixel (infoHeader.getBitsPerPixel ());
			if (infoHeader.getCompression () != 0)	// BI_RGB (uncompressed)
				ErrorAndQuit (Error::Unsupported, "compressed bitmaps unsupported\n");
			//infoHeader.setSizeImage (0);		// lazy
			//infoHeader.setXPixelsPerMeter (0), infoHeader.setYPixelsPerMeter (0);
			infoHeader.setColorsUsed (1 << infoHeader.getBitsPerPixel ());	// make life easier
			//infoHeader.setColorsImportant (infoHeader.getColorsUsed ());

			if (infoHeader.getColorsUsed () != 2)
				ErrorAndQuit (Error::Unsupported, "can't save color BMPs, use WMFs for that purpose\n");

			// colorTable
			BMP_BitmapColorIndex *colorIndex = new BMP_BitmapColorIndex [infoHeader.getColorsUsed ()];
			if (!colorIndex)
				ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for colorIndex[]\n");
			colorIndex [0].setDevice (m_device);
			if (!colorIndex [0].readFromDevice ()) return false;
			if (colorIndex [0].getRed () != 0 || colorIndex [0].getGreen () != 0 || colorIndex [0].getBlue () != 0)
				m_device->error (Error::Warn, "black not black\n");
			colorIndex [1].setDevice (m_device);
			if (!colorIndex [1].readFromDevice ()) return false;
			if (colorIndex [1].getRed () != 0xFF || colorIndex [1].getGreen () != 0xFF || colorIndex [1].getBlue () != 0xFF)
				m_device->error (Error::Warn, "white not white\n");

			// finish reading from m_externalImage
			m_device->setCache (NULL);


			//
			// set image dimensions
			//

			m_MFP_width = Word (Twip2Point (m_originalWidth) * 2.64);
			m_MFP_height = Word (Twip2Point (m_originalHeight) * 2.64);

			// BMPs don't use
			m_width = 0, m_height = 0;

			m_horizontalScalingRel1000 = Word (m_displayedWidth * 1.38889 * 1000.0 / m_originalWidth);
			m_verticalScalingRel1000 = Word (m_displayedHeight * 1.38889 * 1000.0 / m_originalHeight);


			// write header
			setNumDataBytes (infoHeader.getHeight () * scanLineWRILength);
			if (!ImageGenerated::writeToDevice ())
				return false;

			// sanity check
			DWord expectedSize = DWord (infoHeader.getHeight ()) * DWord (scanLineBMPLength);
			DWord imageSize = m_externalImageSize - fileHeader.getActualImageOffset ();
			if (expectedSize != imageSize)
			{
				if (expectedSize > imageSize)
				{
					// better quit instead of reading past end of m_externalImage[]
					ErrorAndQuit (Error::InvalidFormat, "infoHeader.getHeight () * scanLineBMPLength > imageSize\n");
				}
				else
					m_device->error (Error::Warn, "infoHeader.getHeight () * scanLineBMPLength != imageSize\n");
			}

			// the DIB is upside-down...
			Byte *bmpData = m_externalImage + fileHeader.getActualImageOffset () + (infoHeader.getHeight () - 1) * scanLineBMPLength;
			for (int i = (int) infoHeader.getHeight () - 1; i >= 0; i--)
			{
				// write bitmap scanline (padded to 2)
				//if (!m_device->writeInternal (m_externalImage + fileHeader.getActualImageOffset () + i * scanLineBMPLength, scanLineWRILength))
				if (!m_device->writeInternal (bmpData, scanLineWRILength))
					return false;

				bmpData -= scanLineBMPLength;
			}

			delete [] colorIndex;
		}

		return true;
	}
Ejemplo n.º 3
0
	bool Image::readFromDevice (void)
	{
	CHECK_DEVICE;

	#ifdef DEBUG_IMAGE
		m_device->debug ("\n<<<< Image::readFromDevice >>>>\n");
	#endif

		if (!ImageGenerated::readFromDevice ())
			return false;

	#ifdef DEBUG_IMAGE
		Dump (mappingMode);
		Dump (MFP_width);
		Dump (MFP_height);
		Dump (MFP_unknown);

		Dump (indent);
		Dump (width);
		Dump (height);
		Dump (zero);

		Dump (numHeaderBytes);
		Dump (numDataBytes);
		Dump (horizontalScalingRel1000);
		Dump (verticalScalingRel1000);
	#endif

		if (getIsWMF ())
		{
			//
			// get image dimensions
			//

			if (m_bmh->getWidth () || m_bmh->getHeight ())
				m_device->error (Error::Warn, "m_bmh structure should be 0 for WMFs\n");

			m_originalWidth = Milli2Twip (double (m_MFP_width) / 100.0) * 4.0/3.0;
			m_originalHeight = Milli2Twip (double (m_MFP_height) / 100.0) * 4.0/3.0;

			m_displayedWidth = double (m_width);
			m_displayedHeight = double (m_height);

			if (m_horizontalScalingRel1000 != 1000)
				m_device->error (Error::Warn, "horizontal scaling should not be set for WMFs\n");
			if (m_verticalScalingRel1000 != 1000)
				m_device->error (Error::Warn, "vertical scaling should not be set for WMFs\n");


			//
			// read image
			//

			m_externalImage = new Byte [m_externalImageSize = getNumDataBytes ()];
			if (!m_externalImage)
				ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for external WMF image\n");

			if (!m_device->readInternal (m_externalImage, m_externalImageSize))
				ErrorAndQuit (Error::FileError, "could not read internal WMF\n");

			// Header check
			WMFHeader wmfHeader;
			m_device->setCache (m_externalImage);
				wmfHeader.setDevice (m_device);
				if (!wmfHeader.readFromDevice ())
					return false;

				// TODO: fix this incorrect check (see wmf.cpp)
				//if (wmfHeader.getFileSize () * sizeof (Word) != m_numDataBytes)
				//	m_device->error (Error::Warn, "wmfHeader.fileSize != numDataBytes\n");
			m_device->setCache (NULL);
		}
		else	//	if (getIsBMP ())
		{
			//
			// get image dimensions
			//

			m_originalWidth = Point2Twip (DWord (m_bmh->getWidth ()));
			m_originalHeight = Point2Twip (DWord (m_bmh->getHeight ()));

			m_displayedWidth = m_originalWidth / 1.38889 * m_horizontalScalingRel1000 / 1000;
			m_displayedHeight = m_originalHeight / 1.38889 * m_verticalScalingRel1000 / 1000;

#define MSWrite_fabs(val) (((val)>=0)?(val):(-(val)))

			if (MSWrite_fabs (m_MFP_width / double (m_bmh->getWidth ()) - 2.64) > .3)
				m_device->error (Error::Warn, "m_MFP_width != m_bmh->getWidth() * 2.64\n");
			if (MSWrite_fabs (m_MFP_height / double (m_bmh->getHeight ()) - 2.64) > .3)
				m_device->error (Error::Warn, "m_MFP_height != m_bmh->getHeight() * 2.64\n");

#undef MSWrite_fabs

			if (m_width)
				m_device->error (Error::Warn, "m_width should not be set for BMPs\n");

			if (m_height)
				m_device->error (Error::Warn, "m_height should not be set for BMPs\n");


			//
			// read image
			//

			Byte *internalData = new Byte [getNumDataBytes ()];
			if (!internalData)
				ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for internal BMP image\n");
			if (!m_device->readInternal (internalData, getNumDataBytes ()))
				ErrorAndQuit (Error::FileError, "could not read internal BMP\n");

			// infoHeader
			BMP_BitmapInfoHeader infoHeader;
			infoHeader.setWidth (m_bmh->getWidth ());
			infoHeader.setHeight (m_bmh->getHeight ());
			if (m_bmh->getNumPlanes () != 1)
				ErrorAndQuit (Error::InvalidFormat, "bmh.m_numPlanes != 1\n");
			infoHeader.setNumPlanes (m_bmh->getNumPlanes ());
			infoHeader.setBitsPerPixel (m_bmh->getBitsPerPixel ());
			infoHeader.setCompression (0);	// BI_RGB (uncompressed)
			infoHeader.setSizeImage (0);		// lazy
			infoHeader.setXPixelsPerMeter (0), infoHeader.setYPixelsPerMeter (0);
			infoHeader.setColorsUsed (1 << infoHeader.getBitsPerPixel ());
			infoHeader.setColorsImportant (infoHeader.getColorsUsed ());

			if (infoHeader.getColorsUsed () != 2)
				ErrorAndQuit (Error::InternalError, "color bitmap???  Please email this file to <*****@*****.**>\n");

			Word colorTableSize = infoHeader.getColorsUsed () * BMP_BitmapColorIndex::s_size;

			// fileHeader
			BMP_BitmapFileHeader fileHeader;
			DWord fileSize = BMP_BitmapFileHeader::s_size + BMP_BitmapInfoHeader::s_size
										+ colorTableSize
										+ (m_bmh->getHeight ()
											* getBytesPerScanLine (m_bmh->getWidth (), m_bmh->getBitsPerPixel (), 4));

			fileHeader.setTotalBytes (fileSize);
			fileHeader.setActualImageOffset (BMP_BitmapFileHeader::s_size + BMP_BitmapInfoHeader::s_size
														+ colorTableSize);

			// colorTable
			BMP_BitmapColorIndex *colorIndex = new BMP_BitmapColorIndex [infoHeader.getColorsUsed ()];
			if (!colorIndex)
				ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for colorIndex[]\n");


			// black and white...
			colorIndex [0].setRed (0), colorIndex [0].setGreen (0), colorIndex [0].setBlue (0);
			colorIndex [1].setRed (0xFF), colorIndex [1].setGreen (0xFF), colorIndex [1].setBlue (0xFF);

			m_externalImage = new Byte [m_externalImageSize = fileSize];
			if (!m_externalImage)
				ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for external BMP image\n");

			MemoryDevice device;
			device.setCache (m_externalImage);
			fileHeader.setDevice (&device);
			fileHeader.writeToDevice ();
			infoHeader.setDevice (&device);
			infoHeader.writeToDevice ();
			for (int i = 0; i < 2; i++)
			{
				colorIndex [i].setDevice (&device);
				colorIndex [i].writeToDevice ();
			}

			// (BMP padded to 4 bytes vs WRI input bitmap which is actually padded to 2)
			Word scanLineWRILength = getBytesPerScanLine (infoHeader.getWidth (), infoHeader.getBitsPerPixel (), 2);
			if (scanLineWRILength != m_bmh->getWidthBytes ())
				ErrorAndQuit (Error::InvalidFormat, "scanLineWRILength != m_bmh->getWidthBytes()\n");
			Word scanLineBMPLength = getBytesPerScanLine (infoHeader.getWidth (), infoHeader.getBitsPerPixel (), 4);

		#ifdef DEBUG_IMAGE
			m_device->debug ("in: scanLineWRILength: ", scanLineWRILength);
			m_device->debug ("out: scanLineBMPLength: ", scanLineBMPLength);
		#endif

			// sanity check
			DWord expectedSize = DWord (infoHeader.getHeight ()) * DWord (scanLineWRILength);
			if (expectedSize != getNumDataBytes ())
			{
				if (expectedSize > getNumDataBytes ())
				{
					// better quit instead of reading past end of internalData[]
					ErrorAndQuit (Error::InvalidFormat, "infoHeader.getHeight () * scanLineWRILength > numDataBytes\n");
				}
				else
					m_device->error (Error::Warn, "infoHeader.getHeight () * scanLineWRILength != numDataBytes\n");
			}

			Byte *padding = new Byte [scanLineBMPLength - scanLineWRILength];
			if (!padding)
				ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for scanline\n");
			memset (padding, 0, scanLineBMPLength - scanLineWRILength);

			// the DIB is upside-down...
			for (int i = (int) infoHeader.getHeight () - 1; i >= 0; i--)
			{
				// write bitmap scanline
				device.writeInternal (internalData + i * scanLineWRILength, scanLineWRILength * sizeof (Byte));

				// write padding for scanline
				device.writeInternal (padding, (scanLineBMPLength - scanLineWRILength) * sizeof (Byte));
			}

			delete [] padding;

			device.setCache (NULL);

			delete [] colorIndex;
			delete [] internalData;
		}

		return true;
	}