Last modified: Friday, July 03, 2026

pstoedit-3.50のEMFドライバがバスエラーを発生させるのを修正するパッチ

pstoedit, SPARC, SIGBUS

pstoeditはPostScriptファイルを編集可能なベクタ形式ファイルに逆変換するツールです.

pstoedit-3.50のEMFドライバ(drvwmf.cpp)には,big endianかつ厳格なアラインメントを要求する プロセッサ(SPARCなど)でバスエラーを発生させる問題があります. この問題を修正するパッチです.

このパッチはpstoedit-3.60で正式に取り込まれました.

drvwmf.cpp.patch (2010/05/07)



diff -u -r -N pstoedit-3.50/src/drvwmf.cpp pstoedit-3.50.new/src/drvwmf.cpp
--- pstoedit-3.50/src/drvwmf.cpp	2009-06-22 00:10:23.000000000 +0900
+++ pstoedit-3.50.new/src/drvwmf.cpp	2010-05-07 15:21:00.000000000 +0900
@@ -35,6 +35,46 @@
 #define M_PI		3.14159265358979323846
 #endif
 
+#if defined(_BIG_ENDIAN)
+WORD LittleEndian_Word(WORD w)
+{
+	union {
+		WORD data;
+		BYTE b[2];
+	} u1, u2;
+
+	u1.data = w;
+	u2.b[0] = u1.b[1];
+	u2.b[1] = u1.b[0];
+	return u2.data;
+}
+
+DWORD32 LittleEndian_Dword32(DWORD32 dw)
+{
+	union {
+		DWORD32 data;
+		BYTE b[4];
+	} u1, u2;
+
+	u1.data = dw;
+	u2.b[0] = u1.b[3];
+	u2.b[1] = u1.b[2];
+	u2.b[2] = u1.b[1];
+	u2.b[3] = u1.b[0];
+	return u2.data;
+}
+
+#else 
+WORD LittleEndian_Word(WORD w)
+{
+	return w;
+}
+
+DWORD32 LittleEndian_Dword32(DWORD32 dw)
+{
+	return dw;
+}
+#endif /* defined(_BIG_ENDIAN) */
 
 
 //
@@ -80,6 +120,7 @@
 	DWORD32 reserved;
 	WORD checksum;
 };
+#pragma pack()
 
 static const char description[] = "generated by WMF/EMF backend of pstoedit\0input\0\0"; //lint !e840 //usage of nul char in string
 
@@ -450,14 +491,14 @@
 		if ((inFile = fopen(tempName.value(), "rb")) != 0L) {
 			if (outFile != 0L) {
 				// setup header
-				pHd.key = PLACEABLEKEY;
-				pHd.hmf = 0;
-				pHd.left = (WORD) minX;
-				pHd.top = (WORD) minY;
-				pHd.right = (WORD) maxX;
-				pHd.bottom = (WORD) maxY;
-				pHd.inch = 12;
-				pHd.reserved = 0;
+				pHd.key = LittleEndian_Dword32(PLACEABLEKEY);
+				pHd.hmf = LittleEndian_Word(0);
+				pHd.left = LittleEndian_Word((WORD) minX);
+				pHd.top = LittleEndian_Word((WORD) minY);
+				pHd.right = LittleEndian_Word((WORD) maxX);
+				pHd.bottom = LittleEndian_Word((WORD) maxY);
+				pHd.inch = LittleEndian_Word(12);
+				pHd.reserved = LittleEndian_Dword32(0);
 
 				// calculate checksum
 				checksum = 0;
@@ -465,7 +506,7 @@
 				for (unsigned int i = 0; i < 10; i++)
 					checksum ^= checksumField[i];
 
-				pHd.checksum = checksum;
+				pHd.checksum = LittleEndian_Word(checksum);
 
 				// write header
 				if (fwrite(&pHd, PLACEABLESIZE , 1, outFile) != 1) {

布目 淳@京都工芸繊維大学コンピュータシステム研究室 (nunome@kit.ac.jp)