--- Begin Message ---
Package: imagemagick
Version: 5:5.5.7.9-1.1
Severity: normal
Tags: patch
Hi,
Current release of Imagemagick does not support reading images in Matlab
format created in little-endian architectures like powerpc. I've mailed a
patch to fix this to the Imagemagick developer mailing list, but got no
response, see
http://studio.imagemagick.org/pipermail/magick-developers/2004-March/001874.html
Since I anyway need this feature, could this patch perhaps be included in
the Debian release of Imagemagick + libraries?
Teemu
--- mat.c.orig 2004-03-03 18:06:42.000000000 +0200
+++ mat.c.mod 2004-03-05 15:14:26.000000000 +0200
@@ -59,7 +59,8 @@
typedef struct
{
char identific[125];
- char idx[3];
+ unsigned short Version;
+ unsigned short Magic;
unsigned long unknown0;
unsigned long ObjectSize;
unsigned long unknown1;
@@ -72,7 +73,7 @@
unsigned long SizeX;
unsigned long SizeY;
- unsigned short Flag1;
+ unsigned short NameComprSize;
unsigned short NameFlag;
}
MATHeader;
@@ -213,6 +214,18 @@
(void) SeekBlob(I, len, SEEK_CUR);
}
+/*This function reads one block of unsigned shortS*/
+static void ReadBlobWordMSB(Image * I, size_t len, unsigned short *data)
+{
+ while (len >= 2)
+ {
+ *data++ = ReadBlobMSBShort(I);
+ len -= 2;
+ }
+ if (len > 0)
+ (void) SeekBlob(I, len, SEEK_CUR);
+}
+
static double ReadBlobLSBdouble(Image * image)
{
typedef union
@@ -258,6 +271,52 @@
if (len > 0)
(void) SeekBlob(I, len, SEEK_CUR);
}
+
+static double ReadBlobMSBdouble(Image * image)
+{
+ typedef union
+ {
+ double d;
+ char chars[8];
+ }
+ dbl;
+ static unsigned long lsb_first = 1;
+ dbl buffer;
+ char c;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+
+ if (ReadBlob(image, 8, (unsigned char *) &buffer) == 0)
+ return (0.0);
+ if (!(*(char *) &lsb_first == 1))
+ return (buffer.d);
+
+ c = buffer.chars[0];
+ buffer.chars[0] = buffer.chars[7];
+ buffer.chars[7] = c;
+ c = buffer.chars[1];
+ buffer.chars[1] = buffer.chars[6];
+ buffer.chars[6] = c;
+ c = buffer.chars[2];
+ buffer.chars[2] = buffer.chars[5];
+ buffer.chars[5] = c;
+ c = buffer.chars[3];
+ buffer.chars[3] = buffer.chars[4];
+ buffer.chars[4] = c;
+ return (buffer.d);
+}
+
+static void ReadBlobDoublesMSB(Image * I, size_t len, double *data)
+{
+ while (len >= 8)
+ {
+ *data++ = ReadBlobMSBdouble(I);
+ len -= sizeof(double);
+ }
+ if (len > 0)
+ (void) SeekBlob(I, len, SEEK_CUR);
+}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -276,7 +335,7 @@
%
% The format of the ReadMATImage method is:
%
-% Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo
*exception)
+% Image *ReadMATImage(const ImageInfo *image_info,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
@@ -300,7 +359,9 @@
ExtendedSignedIntegralType filepos;
unsigned long CellType;
int i,
- x;
+ x,
+ temp,
+ lsb = 1;
long ldblk;
unsigned char *BImgBuff = NULL;
double Min,
@@ -318,57 +379,91 @@
/*
Read MATLAB image.
*/
- (void) ReadBlob(image, 125, &MATLAB_HDR.identific);
- (void) ReadBlob(image, 3, &MATLAB_HDR.idx);
- MATLAB_HDR.unknown0 = ReadBlobLSBLong(image);
- MATLAB_HDR.ObjectSize = ReadBlobLSBLong(image);
- MATLAB_HDR.unknown1 = ReadBlobLSBLong(image);
- MATLAB_HDR.unknown2 = ReadBlobLSBLong(image);
- MATLAB_HDR.StructureFlag = ReadBlobLSBLong(image);
- MATLAB_HDR.unknown3 = ReadBlobLSBLong(image);
- MATLAB_HDR.unknown4 = ReadBlobLSBLong(image);
- MATLAB_HDR.DimFlag = ReadBlobLSBLong(image);
- MATLAB_HDR.SizeX = ReadBlobLSBLong(image);
- MATLAB_HDR.SizeY = ReadBlobLSBLong(image);
- MATLAB_HDR.Flag1 = ReadBlobLSBShort(image);
- MATLAB_HDR.NameFlag = ReadBlobLSBShort(image);
+ (void) ReadBlob(image, 124, &MATLAB_HDR.identific);
+ MATLAB_HDR.identific[124] = '\0';
+ MATLAB_HDR.Version = ReadBlobLSBShort(image);
+ MATLAB_HDR.Magic = ReadBlobLSBShort(image);
+ /* printf("MATLAB_HDR.magic %lx\n",MATLAB_HDR.magic); */
+ if (MATLAB_HDR.Magic == 0x4d49)
+ lsb = 1;
+ else if (MATLAB_HDR.Magic == 0x494d)
+ lsb = 0;
+ else
+ goto MATLAB_KO;
+
+ /* version is stored as MSB short in LSB files and vice versa */
+ MATLAB_HDR.Version = ((MATLAB_HDR.Version >> 8) & 0xff)
+ + ((MATLAB_HDR.Version & 0xff) << 8);
+
+ if(lsb) {
+ MATLAB_HDR.unknown0 = ReadBlobLSBLong(image);
+ MATLAB_HDR.ObjectSize = ReadBlobLSBLong(image);
+ MATLAB_HDR.unknown1 = ReadBlobLSBLong(image);
+ MATLAB_HDR.unknown2 = ReadBlobLSBLong(image);
+ MATLAB_HDR.StructureFlag = ReadBlobLSBLong(image);
+ MATLAB_HDR.unknown3 = ReadBlobLSBLong(image);
+ MATLAB_HDR.unknown4 = ReadBlobLSBLong(image);
+ MATLAB_HDR.DimFlag = ReadBlobLSBLong(image);
+ MATLAB_HDR.SizeX = ReadBlobLSBLong(image);
+ MATLAB_HDR.SizeY = ReadBlobLSBLong(image);
+ temp = ReadBlobLSBLong(image);
+ } else {
+ MATLAB_HDR.unknown0 = ReadBlobMSBLong(image);
+ MATLAB_HDR.ObjectSize = ReadBlobMSBLong(image);
+ MATLAB_HDR.unknown1 = ReadBlobMSBLong(image);
+ MATLAB_HDR.unknown2 = ReadBlobMSBLong(image);
+ MATLAB_HDR.StructureFlag = ReadBlobMSBLong(image);
+ MATLAB_HDR.unknown3 = ReadBlobMSBLong(image);
+ MATLAB_HDR.unknown4 = ReadBlobMSBLong(image);
+ MATLAB_HDR.DimFlag = ReadBlobMSBLong(image);
+ MATLAB_HDR.SizeX = ReadBlobMSBLong(image);
+ MATLAB_HDR.SizeY = ReadBlobMSBLong(image);
+ temp = ReadBlobMSBLong(image);
+ }
+ MATLAB_HDR.NameComprSize = (temp >> 16) & 0xffff;
+ MATLAB_HDR.NameFlag = temp & 0xffff;
+
if (strncmp(MATLAB_HDR.identific, "MATLAB", 6))
- MATLAB_KO:ThrowReaderException(CorruptImageError, "NotAMATLABImageFile",
+ MATLAB_KO:
+ ThrowReaderException(CorruptImageError, "NotAMATLABImageFile",
image);
- if (strncmp(MATLAB_HDR.idx, "\1IM", 3))
- goto MATLAB_KO;
+ /* printf("MATLAB_HDR.unknown0 %lx\n",MATLAB_HDR.unknown0); */
if (MATLAB_HDR.unknown0 != 0x0E)
goto MATLAB_KO;
if (MATLAB_HDR.DimFlag != 8)
ThrowReaderException(CoderError, "MultidimensionalMatricesAreNotSupported",
image);
- /*printf("MATLAB_HDR.StructureFlag %ld\n",MATLAB_HDR.StructureFlag); */
+ /* printf("MATLAB_HDR.StructureFlag %ld\n",MATLAB_HDR.StructureFlag); */
if (MATLAB_HDR.StructureFlag != 6 && MATLAB_HDR.StructureFlag != 0x806)
goto MATLAB_KO;
- switch (MATLAB_HDR.NameFlag)
- {
- case 0:
- (void) ReadBlob(image, 4, &size); /*Object name string */
- size = 4 * (long) ((size + 3 + 1) / 4);
+ /* printf("MATLAB_HDR.NameFlag %lx\n",MATLAB_HDR.NameFlag);
+ printf("MATLAB_HDR.NameComprSize %lx\n",MATLAB_HDR.NameComprSize); */
+
+ if(MATLAB_HDR.NameComprSize > 0) {
+ size = 4 * (long) ((MATLAB_HDR.NameComprSize + 3) / 4);
+ (void) SeekBlob(image, size, SEEK_CUR);
+ } else {
+ if(lsb)
+ size = ReadBlobLSBLong(image);
+ else
+ size = ReadBlobMSBLong(image);
+ size = 4 * (long) ((size + 3) / 4);
(void) SeekBlob(image, size, SEEK_CUR);
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- (void) ReadBlob(image, 4, &size); /*Object name string */
- break;
- default:
- goto MATLAB_KO;
}
-
- CellType = ReadBlobLSBLong(image); /*Additional object type */
- /*fprintf(stdout,"Cell type:%ld\n",CellType); */
- (void) ReadBlob(image, 4, &size); /*data size */
-
+
+ if(lsb) {
+ CellType = ReadBlobLSBLong(image); /*Additional object type */
+ /* fprintf(stdout,"Cell type:%ld\n",CellType); */
+ size = ReadBlobLSBLong(image); /*data size */
+ } else {
+ CellType = ReadBlobMSBLong(image); /*Additional object type */
+ /* fprintf(stdout,"Cell type:%ld\n",CellType); */
+ size = ReadBlobMSBLong(image); /*data size */
+ }
+
switch (CellType)
{
case 2:
@@ -388,12 +483,13 @@
if (sizeof(double) != 8)
ThrowReaderException(CoderError, "IncompatibleSizeOfDouble", image);
if (MATLAB_HDR.StructureFlag == 0x806)
- { /*complex double type cell */
- }
+ { /*complex double type cell */
+ }
ldblk = (long) (8 * MATLAB_HDR.SizeX);
break;
default:
- ThrowReaderException(CoderError, "UnsupportedCellTypeInTheMatrix", image)}
+ ThrowReaderException(CoderError,
+ "UnsupportedCellTypeInTheMatrix", image)}
image->columns = MATLAB_HDR.SizeX;
image->rows = MATLAB_HDR.SizeY;
@@ -408,8 +504,10 @@
image->colors = 256;
if (!AllocateImageColormap(image, image->colors))
{
- NoMemory:ThrowReaderException(ResourceLimitError, "MemoryAllocationFailed",
- image)}
+ NoMemory:ThrowReaderException(ResourceLimitError,
+ "MemoryAllocationFailed",
+ image)
+ }
for (i = 0; i < (long) image->colors; i++)
{
@@ -431,7 +529,11 @@
filepos = TellBlob(image);
for (i = 0; i < (long) MATLAB_HDR.SizeY; i++)
{
- ReadBlobDoublesLSB(image, ldblk, (double *) BImgBuff);
+ if(lsb) {
+ ReadBlobDoublesLSB(image, ldblk, (double *) BImgBuff);
+ } else {
+ ReadBlobDoublesMSB(image, ldblk, (double *) BImgBuff);
+ }
dblrow = (double *) BImgBuff;
if (i == 0)
{
@@ -455,13 +557,21 @@
switch (CellType)
{
case 4:
- ReadBlobWordLSB(image, ldblk, (unsigned short *) BImgBuff);
- InsertRow(BImgBuff, i, image);
- break;
+ if(lsb) {
+ ReadBlobWordLSB(image, ldblk, (unsigned short *) BImgBuff);
+ } else {
+ ReadBlobWordMSB(image, ldblk, (unsigned short *) BImgBuff);
+ }
+ InsertRow(BImgBuff, i, image);
+ break;
case 9:
- ReadBlobDoublesLSB(image, ldblk, (double *) BImgBuff);
- InsertFloatRow((double *) BImgBuff, i, image, Min, Max);
- break;
+ if(lsb) {
+ ReadBlobDoublesLSB(image, ldblk, (double *) BImgBuff);
+ } else {
+ ReadBlobDoublesMSB(image, ldblk, (double *) BImgBuff);
+ }
+ InsertFloatRow((double *) BImgBuff, i, image, Min, Max);
+ break;
default:
(void) ReadBlob(image, ldblk, (char *) BImgBuff);
InsertRow(BImgBuff, i, image);
@@ -471,12 +581,16 @@
/*Read complex part of numbers here */
if (MATLAB_HDR.StructureFlag == 0x806)
{
- if (CellType == 9) /*Find Min and Max Values for complex parts of
floats */
+ if (CellType == 9) /*Find Min and Max Values for complex parts of floats */
{
filepos = TellBlob(image);
for (i = 0; i < (long) MATLAB_HDR.SizeY; i++)
{
- ReadBlobDoublesLSB(image, ldblk, (double *) BImgBuff);
+ if(lsb) {
+ ReadBlobDoublesLSB(image, ldblk, (double *) BImgBuff);
+ } else {
+ ReadBlobDoublesMSB(image, ldblk, (double *) BImgBuff);
+ }
dblrow = (double *) BImgBuff;
if (i == 0)
{
@@ -495,7 +609,11 @@
for (i = 0; i < (long) MATLAB_HDR.SizeY; i++)
{
- ReadBlobDoublesLSB(image, ldblk, (double *) BImgBuff);
+ if(lsb) {
+ ReadBlobDoublesLSB(image, ldblk, (double *) BImgBuff);
+ } else {
+ ReadBlobDoublesMSB(image, ldblk, (double *) BImgBuff);
+ }
InsertComplexFloatRow((double *) BImgBuff, i, image, Min, Max);
}
}
--- End Message ---