00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
#include "magick/studio.h"
00051
#include "magick/blob.h"
00052
#include "magick/blob_private.h"
00053
#include "magick/color_private.h"
00054
#include "magick/error.h"
00055
#include "magick/error_private.h"
00056
#include "magick/image.h"
00057
#include "magick/image_private.h"
00058
#include "magick/list.h"
00059
#include "magick/magick.h"
00060
#include "magick/memory_.h"
00061
#include "magick/shear.h"
00062
#include "magick/static.h"
00063
#include "magick/string_.h"
00064
#include "magick/transform.h"
00065
00066 typedef struct
00067
{
00068 char identific[125];
00069 char idx[3];
00070 unsigned short Version;
00071 unsigned short Magic;
00072 unsigned long unknown0;
00073 unsigned long ObjectSize;
00074 unsigned long unknown1;
00075 unsigned long unknown2;
00076
00077 unsigned long StructureFlag;
00078 unsigned long unknown3;
00079 unsigned long unknown4;
00080 unsigned long DimFlag;
00081
00082 unsigned long SizeX;
00083 unsigned long SizeY;
00084 unsigned long Flag1;
00085 unsigned short NameComprSize;
00086 unsigned short NameFlag;
00087 }
00088
MATHeader;
00089
00090 static void InsertRow(
unsigned char *p,
int y,
Image *image)
00091 {
00092
int x;
00093
register PixelPacket *q;
00094
IndexPacket index;
00095
register IndexPacket *indexes;
00096
00097
switch (image->
depth)
00098 {
00099
case 8:
00100 {
00101 q =
SetImagePixels(image, 0, y, image->
columns, 1);
00102
if (q == (
PixelPacket *) NULL)
00103
break;
00104 indexes =
GetIndexes(image);
00105
00106
for (x = 0; x < (
long) image->
columns; x++)
00107 {
00108 index = (
IndexPacket) (*p);
00109
ConstrainColormapIndex(image, index);
00110 indexes[x] = index;
00111 *q++ = image->
colormap[index];
00112 p++;
00113 }
00114
if (
SyncImagePixels(image) ==
MagickFalse)
00115
break;
00116 }
00117
return;
00118
00119
case 16:
00120 {
00121 q =
SetImagePixels(image, 0, y, image->
columns, 1);
00122
if (q == (
PixelPacket *) NULL)
00123
break;
00124
for (x = 0; x < (
long) image->
columns; x++)
00125 {
00126 q->
red =
ScaleShortToQuantum(*(
unsigned short *) p);
00127 q->
green =
ScaleShortToQuantum(*(
unsigned short *) p);
00128 q->
blue =
ScaleShortToQuantum(*(
unsigned short *) p);
00129 p += 2;
00130 q++;
00131 }
00132
if (
SyncImagePixels(image) ==
MagickFalse)
00133
break;
00134
return;
00135 }
00136 }
00137 }
00138
00139 static void InsertFloatRow(
double *p,
int y,
Image * image,
double Min,
00140
double Max)
00141 {
00142
double f;
00143
int x;
00144
register PixelPacket *q;
00145
00146
if (
Min >=
Max)
00147
Max =
Min + 1;
00148
00149 q =
SetImagePixels(image, 0, y, image->
columns, 1);
00150
if (q == (
PixelPacket *) NULL)
00151
return;
00152
for (x = 0; x < (
long) image->
columns; x++)
00153 {
00154 f = (
double)
MaxRGB *(*p -
Min) / (
Max -
Min);
00155 q->
red =
ScaleShortToQuantum(f);
00156 q->
green =
ScaleShortToQuantum(f);
00157 q->
blue =
ScaleShortToQuantum(f);
00158 p++;
00159 q++;
00160 }
00161
if (
SyncImagePixels(image) ==
MagickFalse)
00162
return;
00163
return;
00164 }
00165
00166 static void InsertComplexFloatRow(
double *p,
int y,
Image *image,
double Min,
00167
double Max)
00168 {
00169
double f;
00170
int x;
00171
register PixelPacket *q;
00172
00173
if (
Min == 0)
00174
Min = -1;
00175
if (
Max == 0)
00176
Max = 1;
00177
00178 q =
SetImagePixels(image, 0, y, image->
columns, 1);
00179
if (q == (
PixelPacket *) NULL)
00180
return;
00181
for (x = 0; x < (
long) image->
columns; x++)
00182 {
00183
if (*p > 0)
00184 {
00185 f = (*p /
Max) * (
MaxRGB - q->
red);
00186
if (f + q->
red >
MaxRGB)
00187 q->
red =
MaxRGB;
00188
else
00189 q->
red += (
int) f;
00190
if ((
int) f / 2.0 > q->
green)
00191 q->
green = q->
blue = 0;
00192
else
00193 q->
green = q->
blue -= (
int) (f / 2.0);
00194 }
00195
if (*p < 0)
00196 {
00197 f = (*p /
Max) * (
MaxRGB - q->
blue);
00198
if (f + q->
blue >
MaxRGB)
00199 q->
blue =
MaxRGB;
00200
else
00201 q->
blue += (
int) f;
00202
if ((
int) f / 2.0 > q->
green)
00203 q->
green = q->
red = 0;
00204
else
00205 q->
green = q->
red -= (
int) (f / 2.0);
00206 }
00207 p++;
00208 q++;
00209 }
00210
if (
SyncImagePixels(image) ==
MagickFalse)
00211
return;
00212
return;
00213 }
00214
00215
00216 static void ReadBlobWordLSB(
Image *image,size_t len,
unsigned short *data)
00217 {
00218
while (len >= 2)
00219 {
00220 *data++ =
ReadBlobLSBShort(image);
00221 len -= 2;
00222 }
00223
if (len > 0)
00224 (
void)
SeekBlob(image,len,SEEK_CUR);
00225 }
00226
00227
00228 static void ReadBlobWordMSB(
Image *image, size_t len,
unsigned short *data)
00229 {
00230
while (len >= 2)
00231 {
00232 *data++ =
ReadBlobMSBShort(image);
00233 len -= 2;
00234 }
00235
if (len > 0)
00236 (
void)
SeekBlob(image,len,SEEK_CUR);
00237 }
00238
00239 static double ReadBlobLSBdouble(
Image *image)
00240 {
00241
typedef union
00242
{
00243
double d;
00244
char chars[8];
00245 }
00246 dbl;
00247
static unsigned long lsb_first = 1;
00248 dbl buffer;
00249
char c;
00250
00251
assert(image != (
Image *) NULL);
00252
assert(image->
signature ==
MagickSignature);
00253
if (image->
debug !=
MagickFalse)
00254 (
void)
LogMagickEvent(
TraceEvent,
GetMagickModule(),image->
filename);
00255
if (
ReadBlob(image, 8, (
unsigned char *) &buffer) == 0)
00256
return(0.0);
00257
if (*(
char *) &lsb_first == 1)
00258
return (buffer.d);
00259
00260 c = buffer.chars[0];
00261 buffer.chars[0] = buffer.chars[7];
00262 buffer.chars[7] = c;
00263 c = buffer.chars[1];
00264 buffer.chars[1] = buffer.chars[6];
00265 buffer.chars[6] = c;
00266 c = buffer.chars[2];
00267 buffer.chars[2] = buffer.chars[5];
00268 buffer.chars[5] = c;
00269 c = buffer.chars[3];
00270 buffer.chars[3] = buffer.chars[4];
00271 buffer.chars[4] = c;
00272
return (buffer.d);
00273 }
00274
00275 static void ReadBlobDoublesLSB(
Image *image, size_t len,
double *data)
00276 {
00277
while (len >= 8)
00278 {
00279 *data++ =
ReadBlobLSBdouble(image);
00280 len -=
sizeof(
double);
00281 }
00282
if (len > 0)
00283 (
void)
SeekBlob(image,len,SEEK_CUR);
00284 }
00285
00286 static double ReadBlobMSBdouble(
Image *image)
00287 {
00288
typedef union
00289
{
00290
double d;
00291
char chars[8];
00292 }
00293 dbl;
00294
static unsigned long lsb_first = 1;
00295 dbl buffer;
00296
char c;
00297
00298
assert(image != (
Image *) NULL);
00299
assert(image->
signature ==
MagickSignature);
00300
00301
if (
ReadBlob(image, 8, (
unsigned char *) &buffer) == 0)
00302
return (0.0);
00303
if (!(*(
char *) &lsb_first == 1))
00304
return (buffer.d);
00305
00306 c = buffer.chars[0];
00307 buffer.chars[0] = buffer.chars[7];
00308 buffer.chars[7] = c;
00309 c = buffer.chars[1];
00310 buffer.chars[1] = buffer.chars[6];
00311 buffer.chars[6] = c;
00312 c = buffer.chars[2];
00313 buffer.chars[2] = buffer.chars[5];
00314 buffer.chars[5] = c;
00315 c = buffer.chars[3];
00316 buffer.chars[3] = buffer.chars[4];
00317 buffer.chars[4] = c;
00318
return (buffer.d);
00319 }
00320
00321 static void ReadBlobDoublesMSB(
Image *image,size_t len,
double *data)
00322 {
00323
while (len >= 8)
00324 {
00325 *data++ =
ReadBlobMSBdouble(image);
00326 len -=
sizeof(
double);
00327 }
00328
if (len > 0)
00329 (
void)
SeekBlob(image,len,SEEK_CUR);
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 static Image *
ReadMATImage(
const ImageInfo *image_info,
ExceptionInfo *
exception)
00360 {
00361
Image *image,
00362 *rotated_image;
00363
MagickBooleanType status;
00364
MATHeader MATLAB_HDR;
00365
unsigned long size;
00366
MagickOffsetType filepos;
00367
unsigned long CellType;
00368
int i,
00369 x,
00370 lsb = 1;
00371
long ldblk;
00372
unsigned char *BImgBuff = NULL;
00373
double Min,
00374
Max,
00375 *dblrow;
00376
00377
00378
00379
00380 image=
AllocateImage(image_info);
00381 status=
OpenBlob(image_info,image,
ReadBinaryBlobMode,exception);
00382
if (status ==
MagickFalse)
00383 {
00384
DestroyImageList(image);
00385
return((
Image *) NULL);
00386 }
00387
00388
00389
00390 (
void)
ReadBlob(image, 125, (
unsigned char *) &MATLAB_HDR.
identific);
00391 (
void)
ReadBlob(image, 3, (
unsigned char *) &MATLAB_HDR.
idx);
00392 MATLAB_HDR.
unknown0 =
ReadBlobLSBLong(image);
00393 MATLAB_HDR.
ObjectSize =
ReadBlobLSBLong(image);
00394 MATLAB_HDR.
unknown1 =
ReadBlobLSBLong(image);
00395 MATLAB_HDR.
unknown2 =
ReadBlobLSBLong(image);
00396 MATLAB_HDR.
StructureFlag =
ReadBlobLSBLong(image);
00397 MATLAB_HDR.
unknown3 =
ReadBlobLSBLong(image);
00398 MATLAB_HDR.
unknown4 =
ReadBlobLSBLong(image);
00399 MATLAB_HDR.
DimFlag =
ReadBlobLSBLong(image);
00400 MATLAB_HDR.
SizeX =
ReadBlobLSBLong(image);
00401 MATLAB_HDR.
SizeY =
ReadBlobLSBLong(image);
00402 MATLAB_HDR.
Flag1 =
ReadBlobLSBShort(image);
00403 MATLAB_HDR.
NameFlag =
ReadBlobLSBShort(image);
00404
00405
if (strncmp(MATLAB_HDR.
identific,
"MATLAB", 6))
00406 MATLAB_KO:
ThrowReaderException(
CorruptImageError,
"ImproperImageHeader");
00407
if (strncmp(MATLAB_HDR.
idx,
"\1IM", 3))
00408
goto MATLAB_KO;
00409
if (MATLAB_HDR.
unknown0 != 0x0E)
00410
goto MATLAB_KO;
00411
if (MATLAB_HDR.
DimFlag != 8)
00412
ThrowReaderException(
CoderError,
"MultidimensionalMatricesAreNotSupported");
00413
00414
00415
if (MATLAB_HDR.
StructureFlag != 6 && MATLAB_HDR.
StructureFlag != 0x806)
00416
goto MATLAB_KO;
00417
00418
switch (MATLAB_HDR.
NameFlag)
00419 {
00420
case 0:
00421 (
void)
ReadBlob(image, 4, (
unsigned char *) &size);
00422 size = 4 * (
long) ((size + 3 + 1) / 4);
00423 (
void)
SeekBlob(image, size, SEEK_CUR);
00424
break;
00425
case 1:
00426
case 2:
00427
case 3:
00428
case 4:
00429 (
void)
ReadBlob(image, 4, (
unsigned char *) &size);
00430
break;
00431
default:
00432
goto MATLAB_KO;
00433 }
00434
00435 CellType =
ReadBlobLSBLong(image);
00436
00437 (
void)
ReadBlob(image, 4, (
unsigned char *) &size);
00438
00439
switch (CellType)
00440 {
00441
case 2:
00442 image->
depth =
Min(
QuantumDepth,8);
00443 ldblk = (
long) MATLAB_HDR.
SizeX;
00444
if (MATLAB_HDR.
StructureFlag == 0x806)
00445
goto MATLAB_KO;
00446
break;
00447
case 4:
00448 image->
depth =
Min(
QuantumDepth,16);
00449 ldblk = (
long) (2 * MATLAB_HDR.
SizeX);
00450
if (MATLAB_HDR.
StructureFlag == 0x806)
00451
goto MATLAB_KO;
00452
break;
00453
case 9:
00454 image->
depth =
Min(
QuantumDepth,32);
00455
if (
sizeof(
double) != 8)
00456
ThrowReaderException(
CoderError,
"IncompatibleSizeOfDouble");
00457
if (MATLAB_HDR.
StructureFlag == 0x806)
00458 {
00459 }
00460 ldblk = (
long) (8 * MATLAB_HDR.
SizeX);
00461
break;
00462
default:
00463
ThrowReaderException(
CoderError,
"UnsupportedCellTypeInTheMatrix");
00464 }
00465
00466 image->
columns = MATLAB_HDR.
SizeX;
00467 image->
rows = MATLAB_HDR.
SizeY;
00468 image->
colors = 1l >> 8;
00469
if (image->
columns == 0 || image->
rows == 0)
00470
goto MATLAB_KO;
00471
00472
00473
00474
if (CellType == 2)
00475 {
00476 image->
colors = 256;
00477
if (
AllocateImageColormap(image, image->
colors) ==
MagickFalse)
00478 {
00479 NoMemory:
ThrowReaderException(
ResourceLimitError,
"MemoryAllocationFailed");
00480 }
00481
00482
for (i = 0; i < (
long) image->
colors; i++)
00483 {
00484 image->
colormap[i].
red =
ScaleCharToQuantum(i);
00485 image->
colormap[i].
green =
ScaleCharToQuantum(i);
00486 image->
colormap[i].
blue =
ScaleCharToQuantum(i);
00487 }
00488 }
00489
00490
00491 BImgBuff = (
unsigned char *)
AcquireMagickMemory(ldblk);
00492
if (BImgBuff == NULL)
00493
goto NoMemory;
00494
00495
Min = 0;
00496
Max = 0;
00497
if (CellType == 9)
00498 {
00499 filepos =
TellBlob(image);
00500
for (i = 0; i < (
long) MATLAB_HDR.
SizeY; i++)
00501 {
00502
if(lsb) {
00503
ReadBlobDoublesLSB(image, ldblk, (
double *) BImgBuff);
00504 }
else {
00505
ReadBlobDoublesMSB(image, ldblk, (
double *) BImgBuff);
00506 }
00507 dblrow = (
double *) BImgBuff;
00508
if (i == 0)
00509 {
00510
Min =
Max = *dblrow;
00511 }
00512
for (x = 0; x < (
long) MATLAB_HDR.
SizeX; x++)
00513 {
00514
if (
Min > *dblrow)
00515
Min = *dblrow;
00516
if (
Max < *dblrow)
00517
Max = *dblrow;
00518 dblrow++;
00519 }
00520 }
00521
SeekBlob(image, filepos, SEEK_SET);
00522 }
00523
00524
00525
for (i = 0; i < (
long) MATLAB_HDR.
SizeY; i++)
00526 {
00527
switch (CellType)
00528 {
00529
case 4:
00530
if(lsb) {
00531
ReadBlobWordLSB(image, ldblk, (
unsigned short *) BImgBuff);
00532 }
else {
00533
ReadBlobWordMSB(image, ldblk, (
unsigned short *) BImgBuff);
00534 }
00535
InsertRow(BImgBuff, i, image);
00536
break;
00537
case 9:
00538
if(lsb) {
00539
ReadBlobDoublesLSB(image, ldblk, (
double *) BImgBuff);
00540 }
else {
00541
ReadBlobDoublesMSB(image, ldblk, (
double *) BImgBuff);
00542 }
00543
InsertFloatRow((
double *) BImgBuff, i, image,
Min,
Max);
00544
break;
00545
default:
00546 (
void)
ReadBlob(image, ldblk, BImgBuff);
00547
InsertRow(BImgBuff, i, image);
00548 }
00549 }
00550
00551
00552
if (MATLAB_HDR.
StructureFlag == 0x806)
00553 {
00554
if (CellType == 9)
00555 {
00556 filepos =
TellBlob(image);
00557
for (i = 0; i < (
long) MATLAB_HDR.
SizeY; i++)
00558 {
00559
if(lsb) {
00560
ReadBlobDoublesLSB(image, ldblk, (
double *) BImgBuff);
00561 }
else {
00562
ReadBlobDoublesMSB(image, ldblk, (
double *) BImgBuff);
00563 }
00564 dblrow = (
double *) BImgBuff;
00565
if (i == 0)
00566 {
00567
Min =
Max = *dblrow;
00568 }
00569
for (x = 0; x < (
long) MATLAB_HDR.
SizeX; x++)
00570 {
00571
if (
Min > *dblrow)
00572
Min = *dblrow;
00573
if (
Max < *dblrow)
00574
Max = *dblrow;
00575 dblrow++;
00576 }
00577 }
00578
SeekBlob(image, filepos, SEEK_SET);
00579
00580
for (i = 0; i < (
long) MATLAB_HDR.
SizeY; i++)
00581 {
00582
if(lsb) {
00583
ReadBlobDoublesLSB(image, ldblk, (
double *) BImgBuff);
00584 }
else {
00585
ReadBlobDoublesMSB(image, ldblk, (
double *) BImgBuff);
00586 }
00587
InsertComplexFloatRow((
double *) BImgBuff, i, image,
Min,
Max);
00588 }
00589 }
00590 }
00591
00592
if (BImgBuff != NULL)
00593 {
00594 BImgBuff=(
unsigned char *)
RelinquishMagickMemory(BImgBuff);
00595 BImgBuff = NULL;
00596 }
00597
CloseBlob(image);
00598
00599
00600 rotated_image =
RotateImage(image, 90.0, exception);
00601
if (rotated_image != (
Image *) NULL)
00602 {
00603 image=
DestroyImage(image);
00604 image =
FlopImage(rotated_image, exception);
00605
if (image == NULL)
00606 image = rotated_image;
00607
else
00608 rotated_image=
DestroyImage(rotated_image);
00609 }
00610
00611
return (image);
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 ModuleExport void RegisterMATImage(
void)
00638 {
00639
MagickInfo * entry;
00640
00641 entry=
SetMagickInfo(
"MAT");
00642 entry->
decoder=(
DecoderHandler *)
ReadMATImage;
00643 entry->
seekable_stream=
MagickTrue;
00644 entry->
description=
AcquireString(
"MATLAB image format");
00645 entry->
module=
AcquireString(
"MAT");
00646 (
void)
RegisterMagickInfo(entry);
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 ModuleExport void UnregisterMATImage(
void)
00669 {
00670 (
void)
UnregisterMagickInfo(
"MAT");
00671 }