[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]

[XaraXtreme-commits] Commit Complete



Commit by  : alex
Repository : xara
Revision   : 1463
Date       : Tue Jul 18 13:31:52 BST 2006

Changed paths:
   M /Trunk/XaraLX/Kernel/filter_types.h
   M /Trunk/XaraLX/wxOil/imgmgkft.cpp
   M /Trunk/XaraLX/wxOil/imgmgkft.h
   M /Trunk/XaraLX/wxOil/xrc/EN/imagemagick-strings.xrc

More work on ImageMagick stuff


Diff:
Index: Trunk/XaraLX/Kernel/filter_types.h
===================================================================
--- Trunk/XaraLX/Kernel/filter_types.h	(revision 1462)
+++ Trunk/XaraLX/Kernel/filter_types.h	(revision 1463)
@@ -193,6 +193,9 @@
 	PNG_TRANSINTER,
 
 	IMAGEMAGICK,
+	IMAGEMAGICK_INTERLACED,
+	IMAGEMAGICK_TRANSPARENT,
+	IMAGEMAGICK_TRANSINTER,
 
 	// --- Insert new Filter Types just above here ---
 
Index: Trunk/XaraLX/wxOil/imgmgkft.cpp
===================================================================
--- Trunk/XaraLX/wxOil/imgmgkft.cpp	(revision 1462)
+++ Trunk/XaraLX/wxOil/imgmgkft.cpp	(revision 1463)
@@ -239,6 +239,7 @@
 	// Special Mask prepartion stage ID
 	Export2ndStageMsgID = _R(IDN_MASKINGMSG_IMAGEMAGICK);	// "Preparing mask for ImageMagick file..."
 	ExportRegion = NULL;
+	TempFile = NULL;
 }
 
 /********************************************************************************************
@@ -290,34 +291,11 @@
 INT32 ImageMagickFilter::HowCompatible(PathName& Filename, ADDR HeaderStart, UINT32 HeaderSize, 
 							 UINT32 FileSize)
 {
-PORTNOTE("byteorder", "TODO: Check byte ordering")
 	// We need to remember what we thought of this file in our class variable.
 	// So, set it to a nice default value at the start.
-	ImageMagickHowCompatible = 0;
+	ImageMagickHowCompatible = ((Filename.GetType() == _T("miff")) ||
+							    (Filename.GetType() == _T("miff")) ) ? 10:0;
 
-	// Check that we've got enough data to do our check
-	if (HeaderSize < 8)
-		return 0; // Not enough data - ignore this file.
-
-	// Check the header for the "ImageMagick" signature.
-	// The first eight bytes of a ImageMagick file always contain the following (decimal) values: 
-	// 137 80 78 71 13 10 26 10 
-	if (
-		(HeaderStart[0] == 137) && // 0x89
-		(HeaderStart[1] == 80) && //  0x50
-		(HeaderStart[2] == 78) && //  0x4E
-		(HeaderStart[3] == 71) && //  0x47
-		(HeaderStart[4] == 13) && // Carriage return
-		(HeaderStart[5] == 10) && // Line feed
-		(HeaderStart[6] == 26) && // end of file (0x1a)
-		(HeaderStart[7] == 10)    // Line feed
-	   )
-	{
-		// This should be a good enough check that this is a ImageMagick file
-		// Hence, we like this file
-		ImageMagickHowCompatible = 10;
-	}
-				
 	// Return the found value to the caller.
 	return ImageMagickHowCompatible;
 }
@@ -536,9 +514,9 @@
 		switch (Silliness)
 		{
 		case 0:	s_FilterType = IMAGEMAGICK; break;
-		case 1:	s_FilterType = PNG_INTERLACED; break;
-		case 2:	s_FilterType = PNG_TRANSPARENT; break;
-		case 3:	s_FilterType = PNG_TRANSINTER; break;
+		case 1:	s_FilterType = IMAGEMAGICK_INTERLACED; break;
+		case 2:	s_FilterType = IMAGEMAGICK_TRANSPARENT; break;
+		case 3:	s_FilterType = IMAGEMAGICK_TRANSINTER; break;
 		}
 
 		if (pImageMagickOptions->WantTransparent() && pImageMagickOptions->GetSelectionType() == SELECTION)
@@ -670,7 +648,6 @@
 	// This involves doing a 1 bpp export of the same area and using this to work
 	// out which areas are transparent or not.
 	// Only do this if the user has requested transparency and we outputting at 8bpp
-	BOOL ok = TRUE;
 	BOOL SaveDataOut = TRUE;
 
 	if (BadExportRender)
@@ -682,13 +659,17 @@
 		pTempBitmapMask = NULL;
 	}
 
+	BOOL ok=FALSE;
+
 	// Save the data out if required. Only if we exported ok.
 	if (SaveDataOut && !BadExportRender)
 	{
+		ok = CreateTempFile();
+	
 		if (ok)
 		{
 			// Now that we know the transparent index we can output the ImageMagick header
-			ok = DestImageMagick.OutputPNGHeader(OutputFile, NULL, pImageMagickOptions->WantInterlaced(),
+			ok = DestImageMagick.OutputPNGHeader(TempFile, NULL, pImageMagickOptions->WantInterlaced(),
 										pImageMagickOptions->GetTransparencyIndex(),
 										pImageMagickOptions->GetDepth() <= 8 ? pImageMagickOptions->GetLogicalPalette() : NULL);
 		}
@@ -699,18 +680,32 @@
 		if (ok)
 		{
 			String_64 ProgressString(ExportingMsgID);
-			ProgressString = GetExportProgressString(OutputFile, ExportingMsgID);
+			ProgressString = GetExportProgressString(TempFile, ExportingMsgID);
 			BeginSlowJob(100, FALSE, &ProgressString);
 			
-			DestImageMagick.OutputPNGBits(OutputFile, DestImageMagick.GetDestBitmapBits());
-			
+			ok = DestImageMagick.OutputPNGBits(TempFile, DestImageMagick.GetDestBitmapBits());
+			DestImageMagick.TidyUp();
+			if (ok)
+				ok=ProcessTempFile(OutputFile);
+
 			EndSlowJob();
 		}
+		else
+		{
+			DestImageMagick.TidyUp();
+		}
 	}
+	else
+	{
+		DestImageMagick.TidyUp();
+	}
 
-	ASSERT(ok);
+
+	ERROR1IF(!ok, FALSE, _R(IDE_IMAGEMAGICK_ERROR));
+
+	TidyTempFile();
 	
-	return DestImageMagick.TidyUp();
+	return TRUE;
 }
 
 /********************************************************************************************
@@ -926,17 +921,26 @@
 			Bits[i+3] = ~Bits[i+3];
 	}
 
-	// Output a ImageMagick header for this file, using the RGBQUAD palette rather than a LOGPALETTE
-	DestImageMagick.OutputPNGHeader(File, pInfoHeader, Interlace, TransparentColour, NULL, pPalette);
+	if (CreateTempFile())
+	{
+		// Output a ImageMagick header for this file, using the RGBQUAD palette rather than a LOGPALETTE
+		DestImageMagick.OutputPNGHeader(TempFile, pInfoHeader, Interlace, TransparentColour, NULL, pPalette);
+	
+		// Now write out the bitmap data itself.
+		DestImageMagick.OutputPNGBits(TempFile, Bits, TRUE, pFilter);
+		// The above has set the OutputFile member variable of DestImageMagick. We desperately need to
+		// reset this as otherwise the next bitmap export may go wrong as it calls the tidy up
+		// and so will refer to the deleted CCFile. Oh Er!
+		DestImageMagick.TidyUp();
+		ProcessTempFile(File);
+	}
+	else
+	{
+		DestImageMagick.TidyUp();
+	}
 
-	// Now write out the bitmap data itself.
-	DestImageMagick.OutputPNGBits(File, Bits, TRUE, pFilter);
+	TidyTempFile();
 
-	// The above has set the OutputFile member variable of DestImageMagick. We desperately need to
-	// reset this as otherwise the next bitmap export may go wrong as it calls the tidy up
-	// and so will refer to the deleted CCFile. Oh Er!
-	DestImageMagick.TidyUp();
-
 	// er, we seem to have finished OK so say so
 	return TRUE;
 #else
@@ -978,6 +982,7 @@
 							 String_64* ProgressString )
 {
 #ifdef DO_EXPORT
+
 	ERROR2IF(File==NULL,FALSE,"ImageMagickFilter::WriteToFile File pointer is null");
 	ERROR2IF(Info==NULL,FALSE,"ImageMagickFilter::WriteToFile BitmapInfo pointer is null");
 	ERROR2IF(Bits==NULL,FALSE,"ImageMagickFilter::WriteToFile Bits pointer is null");
@@ -1008,15 +1013,15 @@
 			Interlace 		= FALSE;
 			WantTransparent = FALSE;
 			break;
-		case PNG_INTERLACED:
+		case IMAGEMAGICK_INTERLACED:
 			Interlace 		= TRUE;
 			WantTransparent = FALSE;
 			break;
-		case PNG_TRANSPARENT:
+		case IMAGEMAGICK_TRANSPARENT:
 			Interlace 		= FALSE;
 			WantTransparent = TRUE;
 			break;
-		case PNG_TRANSINTER:
+		case IMAGEMAGICK_TRANSINTER:
 			Interlace 		= TRUE;
 			WantTransparent = TRUE;
 			break;
@@ -1046,26 +1051,39 @@
 		}	
 	}
 
-	// Output the ImageMagick data
-	BOOL ok = TRUE;
-	// Output a ImageMagick header for this file, using the RGBQUAD palette rather than a LOGPALETTE
-	if (Transparent == -1)
-		ok = DestImageMagick.OutputPNGHeader(File, pInfoHeader, Interlace, -1, NULL, pPalette);
-	else
-		ok = DestImageMagick.OutputPNGHeader(File, pInfoHeader, Interlace, Transparent, NULL, pPalette);
+	BOOL ok = CreateTempFile();
 
+	if (ok)
+	{
+		// Output the ImageMagick data
+		// Output a ImageMagick header for this file, using the RGBQUAD palette rather than a LOGPALETTE
+		if (Transparent == -1)
+			ok = DestImageMagick.OutputPNGHeader(TempFile, pInfoHeader, Interlace, -1, NULL, pPalette);
+		else
+			ok = DestImageMagick.OutputPNGHeader(TempFile, pInfoHeader, Interlace, Transparent, NULL, pPalette);
+	}
+
 	// Now write out the bitmap data itself.
 	if (ok)
-		ok = DestImageMagick.OutputPNGBits(File, Bits, TRUE);
-	
+		ok = DestImageMagick.OutputPNGBits(TempFile, Bits, TRUE);
+
+	// Tidy up here anyway
+	DestImageMagick.TidyUp();
+
+	// process it
+	if (ok)
+		ok = ProcessTempFile(File);
+
 	// If started, then stop then progress bar
 	if (ProgressString != NULL)
 		EndSlowJob();
 
+	TidyTempFile();
+
+	ERROR1IF(!ok, FALSE, _R(IDE_IMAGEMAGICK_ERROR));
+
 	// er, we seem to have finished OK so say so
 	return TRUE;
-#else
-	return FALSE;
 #endif
 }
 
@@ -1139,7 +1157,7 @@
 ********************************************************************************************/
 BOOL ImageMagickFilter::WriteFileEnd(void)
 {
-	return DestImageMagick.TidyUp();
+	return TRUE;
 }
 
 /********************************************************************************************
@@ -1217,3 +1235,125 @@
 	PORTNOTETRACE("filters","ImageMagickFilter::AlterPaletteContents - do nothing");
 //	DestImageMagick.AlterExportPalette( pPalette );
 }
+
+
+/********************************************************************************************
+
+>	BOOL ImageMagickFilter::CreateTempFile()
+
+	Author:		Alex Bligh <alex@xxxxxxxxxxx>
+	Created:	18/07/2006
+	Purpose:	Create a temporary file
+	Inputs:		None
+	Outputs:	None
+	Returns:	TRUE on success, FALSE on error
+	Notes:		-
+
+********************************************************************************************/
+
+BOOL ImageMagickFilter::CreateTempFile()
+{
+	if (TempFile)
+		delete TempFile;
+
+	TempFile = new CCDiskFile;
+	if (!TempFile)
+		return FALSE;
+
+	wxFile dummyFile; // to prevent deletion race condition
+	TempFileName = wxFileName::CreateTempFileName(wxEmptyString, &dummyFile);
+	PathName pthFileName=String_256(TempFileName);
+	
+	if (!(TempFile->open(pthFileName, ios::out | ios::trunc | ios::binary)))
+	{
+		::wxRemoveFile(TempFileName);
+		ERROR1(FALSE, _R(IDE_IMAGEMAGICK_ERROR));
+	}
+
+	return TRUE;
+}
+
+
+/********************************************************************************************
+
+>	BOOL ImageMagickFilter::ProcessTempFile(CCLexFile * File)
+
+	Author:		Alex Bligh <alex@xxxxxxxxxxx>
+	Created:	18/07/2006
+	Purpose:	Process the temporary file by calling ImageMagick
+	Inputs:		file - the CCLexFile for the final file
+	Outputs:	None
+	Returns:	TRUE on success, FALSE on error
+	Notes:		-
+
+********************************************************************************************/
+
+BOOL ImageMagickFilter::ProcessTempFile(CCLexFile * File)
+{
+	PathName OutputPath = File->GetPathName();
+	ERROR2IF(!OutputPath.IsValid(), FALSE, "ImageMagickFilter::WriteToFile can only be used on real files");
+
+	ERROR2IF(!TempFile || TempFileName.IsEmpty(), FALSE, "ImageMagickFilter::ProcessTempFile has no temporary file to process");
+	TempFile->close();
+
+	wxChar * cifn;
+	wxChar * cofn;
+	wxChar * pcommand=_T("/usr/bin/convert");
+	wxChar * IMargv[4];
+
+	// get filename in usable form
+	cifn = camStrdup(wxString(_T("png:"))+TempFileName );
+	cofn = camStrdup((const TCHAR *)(OutputPath.GetPath()));
+
+	// Now convert the file
+	IMargv[0]=pcommand;
+	IMargv[1]=cifn;
+	IMargv[2]=cofn;
+	IMargv[3]=NULL;
+	long /*TYPENOTE: Correct*/ ret = ::wxExecute((wxChar **)IMargv, wxEXEC_SYNC);
+	
+	free(cifn);
+	free(cofn);
+
+	if (ret)
+	{
+		TidyTempFile();
+		::wxRemoveFile(wxString((const TCHAR *)(OutputPath.GetPath())));
+		ERROR1(FALSE, _R(IDE_IMAGEMAGICK_ERROR));
+	}
+
+	TidyTempFile(); // ensures filename zapped so it isn't removed later
+
+	return TRUE;		
+}
+
+/********************************************************************************************
+
+>	BOOL ImageMagickFilter::TidyTempFile(BOOL Delete=TRUE)
+
+	Author:		Alex Bligh <alex@xxxxxxxxxxx>
+	Created:	18/07/2006
+	Purpose:	Closes any temporary file, and potentially removes it
+	Inputs:		None
+	Outputs:	None
+	Returns:	TRUE on success, FALSE on error
+	Notes:		-
+
+********************************************************************************************/
+
+BOOL ImageMagickFilter::TidyTempFile(BOOL Delete/*=TRUE*/)
+{
+	if (TempFile)
+	{
+		delete (TempFile);
+		TempFile = NULL;
+	}
+
+	if (!TempFileName.IsEmpty())
+	{
+		if (Delete)
+			::wxRemoveFile(TempFileName);
+		TempFileName = wxEmptyString;
+	}
+	return TRUE;
+}
Index: Trunk/XaraLX/wxOil/xrc/EN/imagemagick-strings.xrc
===================================================================
--- Trunk/XaraLX/wxOil/xrc/EN/imagemagick-strings.xrc	(revision 1462)
+++ Trunk/XaraLX/wxOil/xrc/EN/imagemagick-strings.xrc	(revision 1463)
@@ -52,6 +52,12 @@
                                         <label>ImageMagick</label>
                                 </object>
                         </object>
+                        <object class="sizeritem">
+                                <flag>wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE</flag>
+                                <object class="wxStaticText" name="IDE_IMAGEMAGICK_ERROR">
+                                        <label>ImageMagick failed to convert the file</label>
+                                </object>
+                        </object>
 		</object>
         </object>
 </resource>
Index: Trunk/XaraLX/wxOil/imgmgkft.h
===================================================================
--- Trunk/XaraLX/wxOil/imgmgkft.h	(revision 1462)
+++ Trunk/XaraLX/wxOil/imgmgkft.h	(revision 1463)
@@ -159,6 +159,7 @@
 public:
 
 	ImageMagickFilter();
+	virtual ~ImageMagickFilter() {if (TempFile) delete (TempFile);}
 	BOOL Init();
 
 	virtual INT32 HowCompatible( PathName& Filename, ADDR HeaderStart, UINT32 HeaderSize,
@@ -213,17 +214,21 @@
 	virtual BOOL WriteBitmapToFile(KernelBitmap* pKernelBitmap, double Dpi);
 
 	// this is used for the actual writing of the file
-	static BOOL WriteDataToFile( BOOL End, UINT32 Bpp, UINT32 Compression);
-	static BOOL WriteToFile ( CCLexFile*, LPBITMAPINFO Info, LPBYTE Bits,
+	BOOL WriteDataToFile( BOOL End, UINT32 Bpp, UINT32 Compression);
+	BOOL WriteToFile ( CCLexFile*, LPBITMAPINFO Info, LPBYTE Bits,
 						 	  String_64* ProgressString = NULL);
 
 	// This is the form used for direct saving bitmaps into the native/web file format
-	static BOOL WriteToFile ( CCLexFile*, LPBITMAPINFO Info, LPBYTE Bits,
+	BOOL WriteToFile ( CCLexFile*, LPBITMAPINFO Info, LPBYTE Bits,
 							  BOOL Interlace, INT32 TransparentColour,
 						 	  BaseCamelotFilter* pFilter = NULL);
 
 	void AlterPaletteContents( LPLOGPALETTE pPalette );//ap
 
+	virtual BOOL CreateTempFile();
+	virtual BOOL ProcessTempFile(CCLexFile * File);
+	virtual BOOL TidyTempFile(BOOL Delete = TRUE);
+
 #ifdef DO_EXPORT
 	// The class we use for actually outputting the ImageMagick data and converting from 32 to n bpps
 	static OutputPNG DestImageMagick;
@@ -236,6 +241,9 @@
 
 	// The string to display when exporting the second stage.
 	UINT32 Export2ndStageMsgID;
+
+	CCDiskFile * TempFile;
+	wxString TempFileName;
 };
 
 #endif // INC_ImageMagickFILTR


Xara