13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% FFFFF IIIII TTTTT SSSSS % 73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% F I T SS % 83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% FFF I T SSS % 93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% F I T SS % 103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% F IIIII T SSSSS % 113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Read/Write Flexible Image Transport System Images. % 143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Software Design % 16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy% Cristy % 173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% July 1992 % 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% dedicated to making software imaging solutions freely available. % 223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% You may not use this file except in compliance with the License. You may % 243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% obtain a copy of the License at % 253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% http://www.imagemagick.org/script/license.php % 273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Unless required by applicable law or agreed to in writing, software % 293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% distributed under the License is distributed on an "AS IS" BASIS, % 303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% See the License for the specific language governing permissions and % 323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% limitations under the License. % 333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Include declarations. 413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 424c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h" 434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/attribute.h" 444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h" 454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h" 464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h" 474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h" 484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace.h" 49510d06a3f7063e91993e13d546d5685048248074cristy#include "MagickCore/colorspace-private.h" 504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h" 514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h" 524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h" 534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h" 544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h" 554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h" 564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magick.h" 574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h" 584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h" 594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h" 604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h" 614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h" 624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/property.h" 634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h" 644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/static.h" 654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/statistic.h" 664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h" 674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string-private.h" 684c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h" 693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Forward declarations. 723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define FITSBlocksize 2880UL 743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Forward declarations. 773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 783ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType 791e178e70fb3c956f9fc1e30c3ba863e882666465cristy WriteFITSImage(const ImageInfo *,Image *,ExceptionInfo *); 803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% I s F I T S % 873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% IsFITS() returns MagickTrue if the image format type, identified by the 933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% magick string, is FITS. 943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the IsFITS method is: 963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType IsFITS(const unsigned char *magick,const size_t length) 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o magick: compare image format pattern against these bytes. 1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o length: Specifies the length of the magick string. 1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsFITS(const unsigned char *magick,const size_t length) 1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length < 6) 1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleNCompare((const char *) magick,"IT0",3) == 0) 1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleNCompare((const char *) magick,"SIMPLE",6) == 0) 1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% R e a d F I T S I m a g e % 1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ReadFITSImage() reads a FITS image file and returns it. It allocates the 1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% memory necessary for the new Image structure and returns a pointer to the 1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% new image. 1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the ReadFITSImage method is: 1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Image *ReadFITSImage(const ImageInfo *image_info, 1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ExceptionInfo *exception) 1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image_info: the image info. 1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o exception: return any errors or warnings in this structure. 1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline double GetFITSPixel(Image *image,int bits_per_pixel) 1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (image->depth >> 3) 1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 1: 1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return((double) ReadBlobByte(image)); 1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 2: 1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return((double) ((short) ReadBlobShort(image))); 1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 4: 1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (bits_per_pixel > 0) 1561fe0b879964fa7797e3d68574d297922a47c4034Cristy return((double) ReadBlobSignedLong(image)); 1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return((double) ReadBlobFloat(image)); 1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 8: 1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (bits_per_pixel > 0) 1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return((double) ((MagickOffsetType) ReadBlobLongLong(image))); 1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(ReadBlobDouble(image)); 1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1704d0ca34912f861b25e5ed95e3f624048cb180358cristystatic MagickOffsetType GetFITSPixelExtrema(Image *image, 1714d0ca34912f861b25e5ed95e3f624048cb180358cristy const int bits_per_pixel,double *minima,double *maxima) 1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy double 1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pixel; 1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickOffsetType 1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset; 1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickSizeType 1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_pixels; 1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register MagickOffsetType 1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset=TellBlob(image); 1864d0ca34912f861b25e5ed95e3f624048cb180358cristy if (offset == -1) 1874d0ca34912f861b25e5ed95e3f624048cb180358cristy return(-1); 1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_pixels=(MagickSizeType) image->columns*image->rows; 1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *minima=GetFITSPixel(image,bits_per_pixel); 1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *maxima=(*minima); 1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=1; i < (MagickOffsetType) number_pixels; i++) 1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pixel=GetFITSPixel(image,bits_per_pixel); 1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (pixel < *minima) 1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *minima=pixel; 1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (pixel > *maxima) 1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *maxima=pixel; 1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1994d0ca34912f861b25e5ed95e3f624048cb180358cristy return(SeekBlob(image,offset,SEEK_SET)); 2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 202bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline double GetFITSPixelRange(const size_t depth) 2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return((double) ((MagickOffsetType) GetQuantumRange(depth))); 2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void SetFITSUnsignedPixels(const size_t length, 208f84dc8edf517e117a2c1481d841b37cde852a6e9cristy const size_t bits_per_pixel,const EndianType endian,unsigned char *pixels) 2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 210bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 213f84dc8edf517e117a2c1481d841b37cde852a6e9cristy if (endian != MSBEndian) 214f84dc8edf517e117a2c1481d841b37cde852a6e9cristy pixels+=(bits_per_pixel >> 3)-1; 215bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) length; i++) 2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *pixels^=0x80; 2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pixels+=bits_per_pixel >> 3; 2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadFITSImage(const ImageInfo *image_info, 2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExceptionInfo *exception) 2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy typedef struct _FITSInfo 2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extend, 2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy simple; 2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bits_per_pixel, 2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy columns, 2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy rows, 2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_axes, 2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_planes; 2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy double 2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy min_data, 2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy max_data, 2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy zero, 2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scale; 2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy EndianType 2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy endian; 2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } FITSInfo; 2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *comment, 2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy keyword[9], 251151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy property[MagickPathExtent], 2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy value[73]; 2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy double 2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pixel, 2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy scale; 2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FITSInfo 2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info; 2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Image 2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *image; 2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c; 2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickSizeType 2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_pixels; 2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 273bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i, 2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2774c08aed51c5899665ade97263692328eea4af106cristy register Quantum 2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q; 2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ssize_t 281202de443c199963563857f50153b88fbe65afa80cristy count, 282202de443c199963563857f50153b88fbe65afa80cristy scene, 283202de443c199963563857f50153b88fbe65afa80cristy y; 2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Open image file. 2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image_info != (const ImageInfo *) NULL); 289e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image_info->signature == MagickCoreSignature); 2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image_info->debug != MagickFalse) 2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image_info->filename); 2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(exception != (ExceptionInfo *) NULL); 294e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(exception->signature == MagickCoreSignature); 2959950d57e1124b73f684fb5946e206994cefda628cristy image=AcquireImage(image_info,exception); 2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); 2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == MagickFalse) 2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image=DestroyImageList(image); 3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return((Image *) NULL); 3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize image header. 3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(&fits_info,0,sizeof(fits_info)); 3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.extend=MagickFalse; 3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.simple=MagickFalse; 3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.bits_per_pixel=8; 3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.columns=1; 3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.rows=1; 3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.number_planes=1; 3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.min_data=0.0; 3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.max_data=0.0; 3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.zero=0.0; 3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.scale=1.0; 3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.endian=MSBEndian; 3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Decode image header. 3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (comment=(char *) NULL; EOFBlob(image) == MagickFalse; ) 3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for ( ; EOFBlob(image) == MagickFalse; ) 3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=ReadBlob(image,8,(unsigned char *) keyword); 3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (count != 8) 3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; i < 8; i++) 3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (isspace((int) ((unsigned char) keyword[i])) != 0) 3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 334466802f1ee909e98875e99242aa81bf512526125cristy keyword[i]=tolower((int) ((unsigned char) keyword[i])); 3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy keyword[i]='\0'; 3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count=ReadBlob(image,72,(unsigned char *) value); 338e3216eb99bc9e5c5d003554881083db6463ae109cristy value[72]='\0'; 3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (count != 72) 3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=value; 3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*p == '=') 3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p+=2; 3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (isspace((int) ((unsigned char) *p)) != 0) 3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p++; 3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"end") == 0) 3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"extend") == 0) 3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.extend=(*p == 'T') || (*p == 't') ? MagickTrue : MagickFalse; 3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"simple") == 0) 3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.simple=(*p == 'T') || (*p == 't') ? MagickTrue : MagickFalse; 3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"bitpix") == 0) 355f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy fits_info.bits_per_pixel=StringToLong(p); 3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"naxis") == 0) 357f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy fits_info.number_axes=StringToLong(p); 3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"naxis1") == 0) 359f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy fits_info.columns=StringToLong(p); 3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"naxis2") == 0) 361f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy fits_info.rows=StringToLong(p); 3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"naxis3") == 0) 363f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy fits_info.number_planes=StringToLong(p); 3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"datamax") == 0) 365dbdd0e35efc03c9bccda644f5407db38b7c17eeccristy fits_info.max_data=StringToDouble(p,(char **) NULL); 3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"datamin") == 0) 367dbdd0e35efc03c9bccda644f5407db38b7c17eeccristy fits_info.min_data=StringToDouble(p,(char **) NULL); 3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"bzero") == 0) 369dbdd0e35efc03c9bccda644f5407db38b7c17eeccristy fits_info.zero=StringToDouble(p,(char **) NULL); 3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"bscale") == 0) 371dbdd0e35efc03c9bccda644f5407db38b7c17eeccristy fits_info.scale=StringToDouble(p,(char **) NULL); 3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"comment") == 0) 3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (comment == (char *) NULL) 3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy comment=ConstantString(p); 3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ConcatenateString(&comment,p); 3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(keyword,"xendian") == 0) 3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleNCompare(p,"big",3) == 0) 3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.endian=MSBEndian; 3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.endian=LSBEndian; 3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 386151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(property,MagickPathExtent,"fits:%s",keyword); 387d15e65928aec551b7388c2863de3e3e628e2e0ddcristy (void) SetImageProperty(image,property,p,exception); 3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c=0; 3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy while (((TellBlob(image) % FITSBlocksize) != 0) && (c != EOF)) 3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy c=ReadBlobByte(image); 3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (fits_info.extend == MagickFalse) 3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 39411dc2b8f83c2e99ee6e80724c9ec83985bcf4123cristy if ((fits_info.bits_per_pixel != 8) && (fits_info.bits_per_pixel != 16) && 39511dc2b8f83c2e99ee6e80724c9ec83985bcf4123cristy (fits_info.bits_per_pixel != 32) && (fits_info.bits_per_pixel != 64) && 39611dc2b8f83c2e99ee6e80724c9ec83985bcf4123cristy (fits_info.bits_per_pixel != -32) && (fits_info.bits_per_pixel != -64)) 39711dc2b8f83c2e99ee6e80724c9ec83985bcf4123cristy ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_pixels=(MagickSizeType) fits_info.columns*fits_info.rows; 3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((fits_info.simple != MagickFalse) && (fits_info.number_axes >= 1) && 4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (fits_info.number_axes <= 4) && (number_pixels != 0)) 4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Verify that required image information is defined. 4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (comment != (char *) NULL) 4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 408d15e65928aec551b7388c2863de3e3e628e2e0ddcristy (void) SetImageProperty(image,"comment",comment,exception); 4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy comment=DestroyString(comment); 4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (EOFBlob(image) != MagickFalse) 4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", 4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_pixels=(MagickSizeType) fits_info.columns*fits_info.rows; 4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((fits_info.simple == MagickFalse) || (fits_info.number_axes < 1) || 4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (fits_info.number_axes > 4) || (number_pixels == 0)) 4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowReaderException(CorruptImageError,"ImageTypeNotSupported"); 418bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (scene=0; scene < (ssize_t) fits_info.number_planes; scene++) 4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 420bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy image->columns=(size_t) fits_info.columns; 421bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy image->rows=(size_t) fits_info.rows; 422bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy image->depth=(size_t) (fits_info.bits_per_pixel < 0 ? -1 : 1)* 4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.bits_per_pixel; 4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->endian=fits_info.endian; 425bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy image->scene=(size_t) scene; 4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) 4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->scene >= (image_info->scene+image_info->number_scenes-1)) 4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 429acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy status=SetImageExtent(image,image->columns,image->rows,exception); 430acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy if (status == MagickFalse) 431acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy return(DestroyImageList(image)); 4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize image structure. 4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 435d8b3981c6999bf911461b349e15e704bec7018e8cristy (void) SetImageColorspace(image,GRAYColorspace,exception); 436d8b3981c6999bf911461b349e15e704bec7018e8cristy if ((fits_info.min_data == 0.0) && (fits_info.max_data == 0.0)) 4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4383f6782c0dc3e6887aa0aefc50b3af64dca8bd56fcristy if (fits_info.zero == 0.0) 4394d0ca34912f861b25e5ed95e3f624048cb180358cristy (void) GetFITSPixelExtrema(image,fits_info.bits_per_pixel, 440d8b3981c6999bf911461b349e15e704bec7018e8cristy &fits_info.min_data,&fits_info.max_data); 441d8b3981c6999bf911461b349e15e704bec7018e8cristy else 442bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy fits_info.max_data=GetFITSPixelRange((size_t) 4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info.bits_per_pixel); 4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 446d8b3981c6999bf911461b349e15e704bec7018e8cristy fits_info.max_data=GetFITSPixelRange((size_t) fits_info.bits_per_pixel); 4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Convert FITS pixels to pixel packets. 4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 450d8b3981c6999bf911461b349e15e704bec7018e8cristy scale=QuantumRange/(fits_info.max_data-fits_info.min_data); 451bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=(ssize_t) image->rows-1; y >= 0; y--) 4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); 454acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy if (q == (Quantum *) NULL) 4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 456bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) image->columns; x++) 4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy pixel=GetFITSPixel(image,fits_info.bits_per_pixel); 459163d678c009fa8c11235958390ee6d4ae72e6bb0cristy if ((image->depth == 16) || (image->depth == 32) || 4609dcadc5f0faf65fa11d5c936820bf3d29b251e73cristy (image->depth == 64)) 461f84dc8edf517e117a2c1481d841b37cde852a6e9cristy SetFITSUnsignedPixels(1,image->depth,image->endian, 462f84dc8edf517e117a2c1481d841b37cde852a6e9cristy (unsigned char *) &pixel); 46312142880208887a1ad6de5b954b2ec18e5d8ebb1cristy SetPixelGray(image,ClampToQuantum(scale*(fits_info.scale*(pixel- 46412142880208887a1ad6de5b954b2ec18e5d8ebb1cristy fits_info.min_data)+fits_info.zero)),q); 465ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy q+=GetPixelChannels(image); 4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (SyncAuthenticPixels(image,exception) == MagickFalse) 4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->previous == (Image *) NULL) 4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 471cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, 4724c08aed51c5899665ade97263692328eea4af106cristy image->rows); 4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == MagickFalse) 4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (EOFBlob(image) != MagickFalse) 4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", 4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Proceed to next image. 4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image_info->number_scenes != 0) 4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->scene >= (image_info->scene+image_info->number_scenes-1)) 4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 489bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (scene < (ssize_t) (fits_info.number_planes-1)) 4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Allocate next image structure. 4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 4949950d57e1124b73f684fb5946e206994cefda628cristy AcquireNextImage(image_info,image,exception); 4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (GetNextImageInList(image) == (Image *) NULL) 4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image=DestroyImageList(image); 4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return((Image *) NULL); 4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image=SyncNextImageInList(image); 5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=SetImageProgress(image,LoadImagesTag,TellBlob(image), 5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GetBlobSize(image)); 5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == MagickFalse) 5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloseBlob(image); 5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(GetFirstImageInList(image)); 5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% R e g i s t e r F I T S I m a g e % 5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% RegisterFITSImage() adds attributes for the FITS image format to 5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% the list of supported formats. The attributes include the image format 5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% tag, a method to read and/or write the format, whether the format 5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% supports the saving of more than one frame to the same file or blob, 5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% whether the format supports native in-memory I/O, and a brief 5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% description of the format. 5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the RegisterFITSImage method is: 5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 531bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy% size_t RegisterFITSImage(void) 5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 534bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterFITSImage(void) 5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickInfo 5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *entry; 5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 53906b627a07ff44e1ff93ef1288c9f428066ded10ddirk entry=AcquireMagickInfo("FITS","FITS","Flexible Image Transport System"); 5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry->decoder=(DecodeImageHandler *) ReadFITSImage; 5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry->encoder=(EncodeImageHandler *) WriteFITSImage; 5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry->magick=(IsImageFormatHandler *) IsFITS; 54308e9a113db499034abb5ad8d59b42f8eca3c641cdirk entry->flags^=CoderAdjoinFlag; 54408e9a113db499034abb5ad8d59b42f8eca3c641cdirk entry->flags|=CoderSeekableStreamFlag; 5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) RegisterMagickInfo(entry); 546cbab2d169229a0a8f2509ebff047bb9ada533348dirk entry=AcquireMagickInfo("FITS","FTS","Flexible Image Transport System"); 5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry->decoder=(DecodeImageHandler *) ReadFITSImage; 5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry->encoder=(EncodeImageHandler *) WriteFITSImage; 5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry->magick=(IsImageFormatHandler *) IsFITS; 55008e9a113db499034abb5ad8d59b42f8eca3c641cdirk entry->flags^=CoderAdjoinFlag; 55108e9a113db499034abb5ad8d59b42f8eca3c641cdirk entry->flags|=CoderSeekableStreamFlag; 5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) RegisterMagickInfo(entry); 5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickImageCoderSignature); 5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% U n r e g i s t e r F I T S I m a g e % 5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% UnregisterFITSImage() removes format registrations made by the 5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% FITS module from the list of supported formats. 5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the UnregisterFITSImage method is: 5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% UnregisterFITSImage(void) 5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterFITSImage(void) 5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) UnregisterMagickInfo("FITS"); 5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) UnregisterMagickInfo("FTS"); 5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% W r i t e F I T S I m a g e % 5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% WriteFITSImage() writes a Flexible Image Transport System image to a 5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% file as gray scale intensities [0..255]. 5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the WriteFITSImage method is: 5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType WriteFITSImage(const ImageInfo *image_info, 5981e178e70fb3c956f9fc1e30c3ba863e882666465cristy% Image *image,ExceptionInfo *exception) 5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows. 6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image_info: the image info. 6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: The image. 6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6061e178e70fb3c956f9fc1e30c3ba863e882666465cristy% o exception: return any errors or warnings in this structure. 6071e178e70fb3c956f9fc1e30c3ba863e882666465cristy% 6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteFITSImage(const ImageInfo *image_info, 6101e178e70fb3c956f9fc1e30c3ba863e882666465cristy Image *image,ExceptionInfo *exception) 6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy header[FITSBlocksize], 6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *fits_info; 6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy QuantumInfo 6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *quantum_info; 6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6224c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length; 6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ssize_t 6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count, 6302692d59654732a12061a218a8bc7d969b03061eccristy offset, 6312692d59654732a12061a218a8bc7d969b03061eccristy y; 6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *pixels; 6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Open output image file. 6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image_info != (const ImageInfo *) NULL); 640e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image_info->signature == MagickCoreSignature); 6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 642e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 6453a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy assert(exception != (ExceptionInfo *) NULL); 646e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(exception->signature == MagickCoreSignature); 6471e178e70fb3c956f9fc1e30c3ba863e882666465cristy status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); 6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == MagickFalse) 6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 650af8d391906d11f0a1f2bbf4e2adbc4995c852d33cristy (void) TransformImageColorspace(image,sRGBColorspace,exception); 6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Allocate image memory. 6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info=(char *) AcquireQuantumMemory(FITSBlocksize,sizeof(*fits_info)); 6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (fits_info == (char *) NULL) 6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); 6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(fits_info,' ',FITSBlocksize*sizeof(*fits_info)); 6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize image header. 6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->depth=GetImageQuantumDepth(image,MagickFalse); 6626ea44a9922b30e9f2a54f567ab04bb763ccd7125cristy image->endian=MSBEndian; 6635f766ef8b0cd9906c2c3a56d845828380a251073cristy quantum_info=AcquireQuantumInfo(image_info,image); 6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (quantum_info == (QuantumInfo *) NULL) 6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); 6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset=0; 667b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize, 6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "SIMPLE = T"); 6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 671b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize,"BITPIX = %10ld", 67267e3eab96621f8650c8e73994eba161cea0fd9e6cristy (long) ((quantum_info->format == FloatingPointQuantumFormat ? -1 : 1)* 67367e3eab96621f8650c8e73994eba161cea0fd9e6cristy image->depth)); 6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 676b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize,"NAXIS = %10lu", 677f1d8548abecaf5ca89d453fd9fc0cde77d20672bdirk SetImageGray(image,exception) != MagickFalse ? 2UL : 3UL); 6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 680b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize,"NAXIS1 = %10lu", 681f2faecf9facdbbb14fcba373365f9f691a9658e0cristy (unsigned long) image->columns); 6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 684b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize,"NAXIS2 = %10lu", 685f2faecf9facdbbb14fcba373365f9f691a9658e0cristy (unsigned long) image->rows); 6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 688f1d8548abecaf5ca89d453fd9fc0cde77d20672bdirk if (SetImageGray(image,exception) == MagickFalse) 689fcbcae8c995398624afd038a1b8e327031b11e47cristy { 690b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize, 691fcbcae8c995398624afd038a1b8e327031b11e47cristy "NAXIS3 = %10lu",3UL); 692fcbcae8c995398624afd038a1b8e327031b11e47cristy (void) strncpy(fits_info+offset,header,strlen(header)); 693fcbcae8c995398624afd038a1b8e327031b11e47cristy offset+=80; 694fcbcae8c995398624afd038a1b8e327031b11e47cristy } 695b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize,"BSCALE = %E",1.0); 6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 698b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize,"BZERO = %E", 6993ec9e8d654d290b2d60137f2afe438773016eb61cristy image->depth > 8 ? GetFITSPixelRange(image->depth)/2.0 : 0.0); 7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 702b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize,"DATAMAX = %E", 7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1.0*((MagickOffsetType) GetQuantumRange(image->depth))); 7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 706b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize,"DATAMIN = %E",0.0); 7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->endian == LSBEndian) 7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 711b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize,"XENDIAN = 'SMALL'"); 7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 715b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleString(header,FITSBlocksize,"HISTORY %.72s", 716bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy GetMagickVersion((size_t *) NULL)); 7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(header,"END",FITSBlocksize); 7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) strncpy(fits_info+offset,header,strlen(header)); 7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset+=80; 7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlob(image,FITSBlocksize,(unsigned char *) fits_info); 7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Convert image to fits scale PseudoColor class. 7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 726b3f97ae45019a91b30792a6fa42d81a2689a7025cristy pixels=(unsigned char *) GetQuantumPixels(quantum_info); 727f1d8548abecaf5ca89d453fd9fc0cde77d20672bdirk if (SetImageGray(image,exception) != MagickFalse) 728fcbcae8c995398624afd038a1b8e327031b11e47cristy { 729fcbcae8c995398624afd038a1b8e327031b11e47cristy length=GetQuantumExtent(image,quantum_info,GrayQuantum); 730fcbcae8c995398624afd038a1b8e327031b11e47cristy for (y=(ssize_t) image->rows-1; y >= 0; y--) 731fcbcae8c995398624afd038a1b8e327031b11e47cristy { 7321e178e70fb3c956f9fc1e30c3ba863e882666465cristy p=GetVirtualPixels(image,0,y,image->columns,1,exception); 7334c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 734fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 7354c08aed51c5899665ade97263692328eea4af106cristy length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, 7361e178e70fb3c956f9fc1e30c3ba863e882666465cristy GrayQuantum,pixels,exception); 737fcbcae8c995398624afd038a1b8e327031b11e47cristy if (image->depth == 16) 738f84dc8edf517e117a2c1481d841b37cde852a6e9cristy SetFITSUnsignedPixels(image->columns,image->depth,image->endian, 739f84dc8edf517e117a2c1481d841b37cde852a6e9cristy pixels); 740fcbcae8c995398624afd038a1b8e327031b11e47cristy if (((image->depth == 32) || (image->depth == 64)) && 741fcbcae8c995398624afd038a1b8e327031b11e47cristy (quantum_info->format != FloatingPointQuantumFormat)) 742f84dc8edf517e117a2c1481d841b37cde852a6e9cristy SetFITSUnsignedPixels(image->columns,image->depth,image->endian, 743f84dc8edf517e117a2c1481d841b37cde852a6e9cristy pixels); 744fcbcae8c995398624afd038a1b8e327031b11e47cristy count=WriteBlob(image,length,pixels); 745fcbcae8c995398624afd038a1b8e327031b11e47cristy if (count != (ssize_t) length) 746fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 747fcbcae8c995398624afd038a1b8e327031b11e47cristy status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, 748fcbcae8c995398624afd038a1b8e327031b11e47cristy image->rows); 749fcbcae8c995398624afd038a1b8e327031b11e47cristy if (status == MagickFalse) 750fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 751fcbcae8c995398624afd038a1b8e327031b11e47cristy } 752fcbcae8c995398624afd038a1b8e327031b11e47cristy } 753fcbcae8c995398624afd038a1b8e327031b11e47cristy else 754fcbcae8c995398624afd038a1b8e327031b11e47cristy { 755fcbcae8c995398624afd038a1b8e327031b11e47cristy length=GetQuantumExtent(image,quantum_info,RedQuantum); 756fcbcae8c995398624afd038a1b8e327031b11e47cristy for (y=(ssize_t) image->rows-1; y >= 0; y--) 757fcbcae8c995398624afd038a1b8e327031b11e47cristy { 7581e178e70fb3c956f9fc1e30c3ba863e882666465cristy p=GetVirtualPixels(image,0,y,image->columns,1,exception); 7594c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 760fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 7614c08aed51c5899665ade97263692328eea4af106cristy length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, 7621e178e70fb3c956f9fc1e30c3ba863e882666465cristy RedQuantum,pixels,exception); 763fcbcae8c995398624afd038a1b8e327031b11e47cristy if (image->depth == 16) 764f84dc8edf517e117a2c1481d841b37cde852a6e9cristy SetFITSUnsignedPixels(image->columns,image->depth,image->endian, 765f84dc8edf517e117a2c1481d841b37cde852a6e9cristy pixels); 766fcbcae8c995398624afd038a1b8e327031b11e47cristy if (((image->depth == 32) || (image->depth == 64)) && 767fcbcae8c995398624afd038a1b8e327031b11e47cristy (quantum_info->format != FloatingPointQuantumFormat)) 768f84dc8edf517e117a2c1481d841b37cde852a6e9cristy SetFITSUnsignedPixels(image->columns,image->depth,image->endian, 769f84dc8edf517e117a2c1481d841b37cde852a6e9cristy pixels); 770fcbcae8c995398624afd038a1b8e327031b11e47cristy count=WriteBlob(image,length,pixels); 771fcbcae8c995398624afd038a1b8e327031b11e47cristy if (count != (ssize_t) length) 772fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 773fcbcae8c995398624afd038a1b8e327031b11e47cristy status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, 774fcbcae8c995398624afd038a1b8e327031b11e47cristy image->rows); 775fcbcae8c995398624afd038a1b8e327031b11e47cristy if (status == MagickFalse) 776fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 777fcbcae8c995398624afd038a1b8e327031b11e47cristy } 778fcbcae8c995398624afd038a1b8e327031b11e47cristy length=GetQuantumExtent(image,quantum_info,GreenQuantum); 779fcbcae8c995398624afd038a1b8e327031b11e47cristy for (y=(ssize_t) image->rows-1; y >= 0; y--) 780fcbcae8c995398624afd038a1b8e327031b11e47cristy { 7811e178e70fb3c956f9fc1e30c3ba863e882666465cristy p=GetVirtualPixels(image,0,y,image->columns,1,exception); 7824c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 783fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 7844c08aed51c5899665ade97263692328eea4af106cristy length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, 7851e178e70fb3c956f9fc1e30c3ba863e882666465cristy GreenQuantum,pixels,exception); 786fcbcae8c995398624afd038a1b8e327031b11e47cristy if (image->depth == 16) 787f84dc8edf517e117a2c1481d841b37cde852a6e9cristy SetFITSUnsignedPixels(image->columns,image->depth,image->endian, 788f84dc8edf517e117a2c1481d841b37cde852a6e9cristy pixels); 789fcbcae8c995398624afd038a1b8e327031b11e47cristy if (((image->depth == 32) || (image->depth == 64)) && 790fcbcae8c995398624afd038a1b8e327031b11e47cristy (quantum_info->format != FloatingPointQuantumFormat)) 791f84dc8edf517e117a2c1481d841b37cde852a6e9cristy SetFITSUnsignedPixels(image->columns,image->depth,image->endian, 792f84dc8edf517e117a2c1481d841b37cde852a6e9cristy pixels); 793fcbcae8c995398624afd038a1b8e327031b11e47cristy count=WriteBlob(image,length,pixels); 794fcbcae8c995398624afd038a1b8e327031b11e47cristy if (count != (ssize_t) length) 795fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 796fcbcae8c995398624afd038a1b8e327031b11e47cristy status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, 797fcbcae8c995398624afd038a1b8e327031b11e47cristy image->rows); 798fcbcae8c995398624afd038a1b8e327031b11e47cristy if (status == MagickFalse) 799fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 800fcbcae8c995398624afd038a1b8e327031b11e47cristy } 801fcbcae8c995398624afd038a1b8e327031b11e47cristy length=GetQuantumExtent(image,quantum_info,BlueQuantum); 802fcbcae8c995398624afd038a1b8e327031b11e47cristy for (y=(ssize_t) image->rows-1; y >= 0; y--) 803fcbcae8c995398624afd038a1b8e327031b11e47cristy { 8041e178e70fb3c956f9fc1e30c3ba863e882666465cristy p=GetVirtualPixels(image,0,y,image->columns,1,exception); 8054c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 806fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 8074c08aed51c5899665ade97263692328eea4af106cristy length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, 8081e178e70fb3c956f9fc1e30c3ba863e882666465cristy BlueQuantum,pixels,exception); 809fcbcae8c995398624afd038a1b8e327031b11e47cristy if (image->depth == 16) 810f84dc8edf517e117a2c1481d841b37cde852a6e9cristy SetFITSUnsignedPixels(image->columns,image->depth,image->endian, 811f84dc8edf517e117a2c1481d841b37cde852a6e9cristy pixels); 812fcbcae8c995398624afd038a1b8e327031b11e47cristy if (((image->depth == 32) || (image->depth == 64)) && 813fcbcae8c995398624afd038a1b8e327031b11e47cristy (quantum_info->format != FloatingPointQuantumFormat)) 814f84dc8edf517e117a2c1481d841b37cde852a6e9cristy SetFITSUnsignedPixels(image->columns,image->depth,image->endian, 815f84dc8edf517e117a2c1481d841b37cde852a6e9cristy pixels); 816fcbcae8c995398624afd038a1b8e327031b11e47cristy count=WriteBlob(image,length,pixels); 817fcbcae8c995398624afd038a1b8e327031b11e47cristy if (count != (ssize_t) length) 818fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 819fcbcae8c995398624afd038a1b8e327031b11e47cristy status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, 820fcbcae8c995398624afd038a1b8e327031b11e47cristy image->rows); 821fcbcae8c995398624afd038a1b8e327031b11e47cristy if (status == MagickFalse) 822fcbcae8c995398624afd038a1b8e327031b11e47cristy break; 823fcbcae8c995398624afd038a1b8e327031b11e47cristy } 824fcbcae8c995398624afd038a1b8e327031b11e47cristy } 8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy quantum_info=DestroyQuantumInfo(quantum_info); 8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=(size_t) (FITSBlocksize-TellBlob(image) % FITSBlocksize); 8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length != 0) 8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(fits_info,0,length*sizeof(*fits_info)); 8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlob(image,length,(unsigned char *) fits_info); 8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fits_info=DestroyString(fits_info); 8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloseBlob(image); 8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 836