00138 {
00139
typedef struct _FITSInfo
00140 {
00141
int
00142 simple,
00143 bits_per_pixel,
00144 columns,
00145 rows,
00146 number_axes,
00147 number_scenes;
00148
00149
double
00150 min_data,
00151 max_data,
00152 zero,
00153 scale;
00154 } FITSInfo;
00155
00156
char
00157 keyword[
MaxTextExtent],
00158 value[
MaxTextExtent];
00159
00160
double
00161 exponential[2048],
00162 pixel,
00163 scale,
00164 scaled_pixel;
00165
00166 FITSInfo
00167 fits_info;
00168
00169
Image
00170 *image;
00171
00172
IndexPacket
00173 index;
00174
00175
int
00176 c,
00177 quantum;
00178
00179
long
00180 exponent,
00181 j,
00182 k,
00183 l,
00184 scene,
00185 y;
00186
00187
MagickBooleanType
00188 status,
00189 value_expected;
00190
00191
MagickSizeType
00192 number_pixels;
00193
00194
register IndexPacket
00195 *indexes;
00196
00197
register long
00198 x;
00199
00200
register PixelPacket
00201 *q;
00202
00203
register long
00204 i;
00205
00206
register unsigned char
00207 *p;
00208
00209
ssize_t
00210 count;
00211
00212 size_t
00213 packet_size;
00214
00215
unsigned char
00216 *fits_pixels,
00217 long_quantum[8];
00218
00219
00220
00221
00222
assert(image_info != (
const ImageInfo *) NULL);
00223
assert(image_info->
signature == MagickSignature);
00224
if (image_info->
debug !=
MagickFalse)
00225 (
void)
LogMagickEvent(TraceEvent,
GetMagickModule(),image_info->
filename);
00226
assert(exception != (
ExceptionInfo *) NULL);
00227
assert(exception->
signature == MagickSignature);
00228 image=
AllocateImage(image_info);
00229 status=
OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
00230
if (status ==
MagickFalse)
00231 {
00232
DestroyImageList(image);
00233
return((
Image *) NULL);
00234 }
00235
00236
00237
00238 fits_info.simple=
MagickFalse;
00239 fits_info.bits_per_pixel=8;
00240 fits_info.columns=1;
00241 fits_info.rows=1;
00242 fits_info.number_scenes=1;
00243 fits_info.number_axes=1;
00244 fits_info.min_data=0.0;
00245 fits_info.max_data=0.0;
00246 fits_info.zero=0.0;
00247 fits_info.scale=1.0;
00248
00249
00250
00251 c=
ReadBlobByte(image);
00252
if (c == EOF)
00253 {
00254 image=
DestroyImage(image);
00255
return((
Image *) NULL);
00256 }
00257
for ( ; ; )
00258 {
00259
if (isalnum((
int) ((
unsigned char) c)) == 0)
00260 c=
ReadBlobByte(image);
00261
else
00262 {
00263
register char
00264 *p;
00265
00266
00267
00268
00269 p=keyword;
00270
do
00271 {
00272
if ((size_t) (p-keyword) < (
MaxTextExtent-1))
00273 *p++=(
char) c;
00274 c=
ReadBlobByte(image);
00275 }
while ((isalnum((
int) ((
unsigned char) c)) !=
MagickFalse) ||
00276 ((
int) c ==
'_'));
00277 *p=
'\0';
00278
if (
LocaleCompare(keyword,
"END") == 0)
00279
break;
00280 value_expected=
MagickFalse;
00281
while ((isspace((
int) ((
unsigned char) c)) != 0) || ((
int) c ==
'='))
00282 {
00283
if ((
int) c ==
'=')
00284 value_expected=
MagickTrue;
00285 c=
ReadBlobByte(image);
00286 }
00287
if (value_expected ==
MagickFalse)
00288
continue;
00289 p=value;
00290
while (isalnum(c) || (c ==
'-') || (c ==
'+') || (c ==
'.'))
00291 {
00292
if ((size_t) (p-value) < (
MaxTextExtent-1))
00293 *p++=c;
00294 c=
ReadBlobByte(image);
00295 }
00296 *p=
'\0';
00297
00298
00299
00300
if (
LocaleCompare(keyword,
"SIMPLE") == 0)
00301 fits_info.simple=(
int) ((*value ==
'T') || (*value ==
't'));
00302
if (
LocaleCompare(keyword,
"BITPIX") == 0)
00303 fits_info.bits_per_pixel=atoi(value);
00304
if (
LocaleCompare(keyword,
"NAXIS") == 0)
00305 fits_info.number_axes=atoi(value);
00306
if (
LocaleCompare(keyword,
"NAXIS1") == 0)
00307 fits_info.columns=atoi(value);
00308
if (
LocaleCompare(keyword,
"NAXIS2") == 0)
00309 fits_info.rows=atoi(value);
00310
if (
LocaleCompare(keyword,
"NAXIS3") == 0)
00311 fits_info.number_scenes=atoi(value);
00312
if (
LocaleCompare(keyword,
"DATAMAX") == 0)
00313 fits_info.max_data=atof(value);
00314
if (
LocaleCompare(keyword,
"DATAMIN") == 0)
00315 fits_info.min_data=atof(value);
00316
if (
LocaleCompare(keyword,
"BZERO") == 0)
00317 fits_info.zero=atof(value);
00318
if (
LocaleCompare(keyword,
"BSCALE") == 0)
00319 fits_info.scale=atof(value);
00320 (
void)
SetImageAttribute(image,keyword,value);
00321 }
00322
while ((
TellBlob(image) % 80) != 0)
00323 c=
ReadBlobByte(image);
00324 c=
ReadBlobByte(image);
00325 }
00326
while ((
TellBlob(image) % 2880) != 0)
00327 c=
ReadBlobByte(image);
00328
00329
00330
00331 number_pixels=(
MagickSizeType) fits_info.columns*fits_info.rows;
00332
if ((fits_info.simple == 0) || (fits_info.number_axes < 1) ||
00333 (fits_info.number_axes > 4) || (number_pixels == 0))
00334
ThrowReaderException(CorruptImageError,
"ImageTypeNotSupported");
00335
if (fits_info.bits_per_pixel == -32)
00336 {
00337 exponential[150]=1.0;
00338
for (i=151; i < 256; i++)
00339 exponential[i]=2.0*exponential[i-1];
00340
for (i=149; i >= 0; i--)
00341 exponential[i]=exponential[i+1]/2.0;
00342 }
00343
if (fits_info.bits_per_pixel == -64)
00344 {
00345 exponential[1075]=1.0;
00346
for (i=1076; i < 2048; i++)
00347 exponential[i]=2.0*exponential[i-1];
00348
for (i=1074; i >= 0; i--)
00349 exponential[i]=exponential[i+1]/2.0;
00350 }
00351
for (scene=0; scene < (
long) fits_info.number_scenes; scene++)
00352 {
00353
00354
00355
00356 image->
columns=(
unsigned long) fits_info.columns;
00357 image->
rows=(
unsigned long) fits_info.rows;
00358 image->
depth=fits_info.bits_per_pixel <= 8 ? 8UL :
Min(QuantumDepth,16);
00359 image->
storage_class=
PseudoClass;
00360 image->
scene=(
unsigned long) scene;
00361
if (
AllocateImageColormap(image,1UL << image->
depth) ==
MagickFalse)
00362
ThrowReaderException(ResourceLimitError,
"UnableToAllocateColormap");
00363
if ((image_info->
ping !=
MagickFalse) && (image_info->
number_scenes != 0))
00364
if (image->
scene >= (image_info->
scene+image_info->
number_scenes-1))
00365
break;
00366
00367
00368
00369 packet_size=(size_t) fits_info.bits_per_pixel/8;
00370
if (fits_info.bits_per_pixel < 0)
00371 packet_size=(size_t) (-fits_info.bits_per_pixel/8);
00372 number_pixels=(
MagickSizeType) image->
columns*image->
rows;
00373
if ((packet_size*number_pixels) !=
00374 (
MagickSizeType) ((size_t) (packet_size*number_pixels)))
00375
ThrowReaderException(ResourceLimitError,
"MemoryAllocationFailed");
00376 fits_pixels=(
unsigned char *)
00377
AcquireMagickMemory(packet_size*image->
columns*image->
rows);
00378
if (fits_pixels == (
unsigned char *) NULL)
00379
ThrowReaderException(ResourceLimitError,
"MemoryAllocationFailed");
00380
00381
00382
00383 count=
ReadBlob(image,packet_size*image->
columns*image->
rows,fits_pixels);
00384
if (count == 0)
00385
ThrowReaderException(CorruptImageError,
"InsufficientImageDataInFile");
00386
if ((fits_info.bits_per_pixel > 0) &&
00387 (fits_info.min_data == 0.0) && (fits_info.max_data == 0.0))
00388 fits_info.max_data=(1UL << fits_info.bits_per_pixel)-1;
00389
else
00390 {
00391
00392
00393
00394 p=fits_pixels;
00395 long_quantum[0]=(*p);
00396 quantum=(*p++);
00397
for (j=1; j <= (
long) (packet_size-1); j++)
00398 {
00399 long_quantum[j]=(*p);
00400 quantum=(quantum << 8) | (*p++);
00401 }
00402 pixel=(
double) quantum;
00403
if (fits_info.bits_per_pixel == -32)
00404 {
00405 j=((
long) long_quantum[1] << 16) | ((
long) long_quantum[2] << 8) |
00406 (
long) long_quantum[3];
00407 k=(
int) *long_quantum;
00408 exponent=((k & 127) << 1) | (j >> 23);
00409 *(
float *) long_quantum=
00410 exponential[exponent]*(
float) (j | 0x800000);
00411
if ((exponent | j) == 0)
00412 *(
float *) long_quantum=0.0;
00413
if (k & 128)
00414 *(
float *) long_quantum=(-(*(
float *) long_quantum));
00415 pixel=(
double) (*((
float *) long_quantum));
00416 }
00417
if (fits_info.bits_per_pixel == -64)
00418 {
00419 j=((
long) long_quantum[1] << 24) |
00420 ((
long) long_quantum[2] << 16) |
00421 ((
long) long_quantum[3] << 8) |
00422 (
long) long_quantum[4];
00423 k=(
int) *long_quantum;
00424 l=((
int) long_quantum[5] << 16) | ((
int) long_quantum[6] << 8) |
00425 (
int) long_quantum[7];
00426 exponent=((k & 127) << 4) | (j >> 28);
00427 *(
double *) long_quantum=exponential[exponent]*(16777216.0*
00428 (
double) ((j & 0x0FFFFFFF) | 0x10000000)+(
double) l);
00429
if ((exponent | j | l) == 0)
00430 *(
double *) long_quantum=0.0;
00431
if (k & 128)
00432 *(
double *)long_quantum=(-(*(
double *) long_quantum));
00433 pixel=(
double) (*((
double *) long_quantum));
00434 }
00435 fits_info.min_data=pixel*fits_info.scale-fits_info.zero;
00436 fits_info.max_data=pixel*fits_info.scale-fits_info.zero;
00437
for (i=1; i < (
long) number_pixels; i++)
00438 {
00439 long_quantum[0]=(*p);
00440 quantum=(*p++);
00441
for (j=1; j <= (
long) (packet_size-1); j++)
00442 {
00443 long_quantum[j]=(*p);
00444 quantum=(quantum << 8) | (*p++);
00445 }
00446 pixel=(
double) quantum;
00447
if (fits_info.bits_per_pixel == -32)
00448 {
00449 j=((
long) long_quantum[1] << 16) | ((
long) long_quantum[2] << 8) |
00450 (
long) long_quantum[3];
00451 k=(
int) *long_quantum;
00452 exponent=((k & 127) << 1) | (j >> 23);
00453 *(
float *) long_quantum=
00454 exponential[exponent]*(
float) (j | 0x800000);
00455
if ((exponent | j) == 0)
00456 *(
float *) long_quantum=0.0;
00457
if (k & 128)
00458 *(
float *) long_quantum=(-(*(
float *) long_quantum));
00459 pixel=(
double) (*((
float *) long_quantum));
00460 }
00461
if (fits_info.bits_per_pixel == -64)
00462 {
00463 j=((
long) long_quantum[1] << 24) |
00464 ((
long) long_quantum[2] << 16) |
00465 ((
long) long_quantum[3] << 8) |
00466 (
long) long_quantum[4];
00467 k=(
int) *long_quantum;
00468 l=((
int) long_quantum[5] << 16) | ((
int) long_quantum[6] << 8) |
00469 (
int) long_quantum[7];
00470 exponent=((k & 127) << 4) | (j >> 28);
00471 *(
double *) long_quantum=exponential[exponent]*(16777216.0*
00472 (
double) ((j & 0x0FFFFFFF) | 0x10000000)+(
double) l);
00473
if ((exponent | j | l) == 0)
00474 *(
double *) long_quantum=0.0;
00475
if (k & 128)
00476 *(
double *)long_quantum=(-(*(
double *) long_quantum));
00477 pixel=(
double) (*((
double *) long_quantum));
00478 }
00479 scaled_pixel=pixel*fits_info.scale-fits_info.zero;
00480
if (scaled_pixel < fits_info.min_data)
00481 fits_info.min_data=scaled_pixel;
00482
if (scaled_pixel > fits_info.max_data)
00483 fits_info.max_data=scaled_pixel;
00484 }
00485 }
00486
00487
00488
00489 scale=1.0;
00490
if ((fits_info.bits_per_pixel < 0) || ((fits_info.max_data-
00491 fits_info.min_data) > (
double) ((1UL << image->
depth)-1)))
00492 scale=(
double) ((1UL << image->
depth)-1)/
00493 (fits_info.max_data-fits_info.min_data);
00494 p=fits_pixels;
00495
for (y=(
long) image->
rows-1; y >= 0; y--)
00496 {
00497 q=
SetImagePixels(image,0,y,image->
columns,1);
00498
if (q == (
PixelPacket *) NULL)
00499
break;
00500 indexes=
GetIndexes(image);
00501
for (x=0; x < (
long) image->
columns; x++)
00502 {
00503 long_quantum[0]=(*p);
00504 quantum=(*p++);
00505
for (j=1; j <= (
long) (packet_size-1); j++)
00506 {
00507 long_quantum[j]=(*p);
00508 quantum=(quantum << 8) | (*p++);
00509 }
00510 pixel=(
double) quantum;
00511
if (fits_info.bits_per_pixel == -32)
00512 {
00513 j=((
long) long_quantum[1] << 16) | ((
long) long_quantum[2] << 8) |
00514 (
long) long_quantum[3];
00515 k=(
int) *long_quantum;
00516 exponent=((k & 127) << 1) | (j >> 23);
00517 *(
float *) long_quantum=
00518 exponential[exponent]*(
float) (j | 0x800000);
00519
if ((exponent | j) == 0)
00520 *(
float *) long_quantum=0.0;
00521
if (k & 128)
00522 *(
float *) long_quantum=(-(*(
float *) long_quantum));
00523 pixel=(
double) (*((
float *) long_quantum));
00524 }
00525
if (fits_info.bits_per_pixel == -64)
00526 {
00527 j=((
long) long_quantum[1] << 24) |
00528 ((
long) long_quantum[2] << 16) |
00529 ((
long) long_quantum[3] << 8) |
00530 (
long) long_quantum[4];
00531 k=(
long) *long_quantum;
00532 l=((
long) long_quantum[5] << 16) | ((
long) long_quantum[6] << 8) |
00533 (
long) long_quantum[7];
00534 exponent=(
long) ((((
unsigned long) k & 127) << 4) |
00535 ((
unsigned long) j >> 28));
00536 *(
double *) long_quantum=exponential[exponent]*(16777216.0*
00537 (
double) ((j & 0x0FFFFFFF) | 0x10000000)+(
double) l);
00538
if ((exponent | j | l) == 0)
00539 *(
double *) long_quantum=0.0;
00540
if ((k & 128) != 0)
00541 *(
double *)long_quantum=(-(*(
double *) long_quantum));
00542 pixel=(
double) (*((
double *) long_quantum));
00543 }
00544 scaled_pixel=scale*
00545 (pixel*fits_info.scale-fits_info.min_data-fits_info.zero);
00546 index=(
IndexPacket) ((scaled_pixel < 0.0) ? 0 :
00547 ((
unsigned long) scaled_pixel > ((1UL << image->
depth)-1)) ?
00548 ((1UL << image->
depth)-1) : (
unsigned long) (scaled_pixel+0.5));
00549 index=
ConstrainColormapIndex(image,index);
00550 indexes[x]=index;
00551 *q++=image->
colormap[index];
00552 }
00553
if (
SyncImagePixels(image) ==
MagickFalse)
00554
break;
00555
if ((image->
progress_monitor != (
MagickProgressMonitor) NULL) &&
00556 (
QuantumTick(y,image->
rows) !=
MagickFalse))
00557 {
00558 status=image->
progress_monitor(LoadImageTag,y,image->
rows,
00559 image->
client_data);
00560
if (status ==
MagickFalse)
00561
break;
00562 }
00563 }
00564 fits_pixels=(
unsigned char *)
RelinquishMagickMemory(fits_pixels);
00565
if (
EOFBlob(image) !=
MagickFalse)
00566 {
00567
ThrowFileException(exception,CorruptImageError,
"UnexpectedEndOfFile",
00568 image->
filename);
00569
break;
00570 }
00571
00572
00573
00574
if (image_info->
number_scenes != 0)
00575
if (image->
scene >= (image_info->
scene+image_info->
number_scenes-1))
00576
break;
00577
if (scene < (
long) (fits_info.number_scenes-1))
00578 {
00579
00580
00581
00582
AllocateNextImage(image_info,image);
00583
if (image->
next == (
Image *) NULL)
00584 {
00585
DestroyImageList(image);
00586
return((
Image *) NULL);
00587 }
00588 image=
SyncNextImageInList(image);
00589
if (image->
progress_monitor != (
MagickProgressMonitor) NULL)
00590 {
00591 status=image->
progress_monitor(LoadImagesTag,
TellBlob(image),
00592
GetBlobSize(image),image->
client_data);
00593
if (status ==
MagickFalse)
00594
break;
00595 }
00596 }
00597 }
00598
CloseBlob(image);
00599
return(
GetFirstImageInList(image));
00600 }