1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % SSSSS CCCC RRRR % 7 % SS C R R % 8 % SSS C RRRR % 9 % SS C R R % 10 % SSSSS CCCC R R % 11 % % 12 % % 13 % Read ZX-Spectrum SCREEN$ Format % 14 % % 15 % Software Design % 16 % Catalin Mihaila % 17 % October 2003 % 18 % % 19 % % 20 % Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization % 21 % dedicated to making software imaging solutions freely available. % 22 % % 23 % You may not use this file except in compliance with the License. You may % 24 % obtain a copy of the License at % 25 % % 26 % https://imagemagick.org/script/license.php % 27 % % 28 % Unless required by applicable law or agreed to in writing, software % 29 % distributed under the License is distributed on an "AS IS" BASIS, % 30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31 % See the License for the specific language governing permissions and % 32 % limitations under the License. % 33 % % 34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35 % 36 % 37 */ 38 39 /* 41 Include declarations. 42 */ 43 #include "MagickCore/studio.h" 44 #include "MagickCore/blob.h" 45 #include "MagickCore/blob-private.h" 46 #include "MagickCore/cache.h" 47 #include "MagickCore/exception.h" 48 #include "MagickCore/exception-private.h" 49 #include "MagickCore/image.h" 50 #include "MagickCore/image-private.h" 51 #include "MagickCore/list.h" 52 #include "MagickCore/magick.h" 53 #include "MagickCore/memory_.h" 54 #include "MagickCore/monitor.h" 55 #include "MagickCore/monitor-private.h" 56 #include "MagickCore/pixel-accessor.h" 57 #include "MagickCore/quantum-private.h" 58 #include "MagickCore/static.h" 59 #include "MagickCore/string_.h" 60 #include "MagickCore/module.h" 61 62 /* 64 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 % % 66 % % 67 % % 68 % R e a d S C R I m a g e % 69 % % 70 % % 71 % % 72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 73 % 74 % ReadSCRImage() reads a Scitex image file and returns it. It allocates 75 % the memory necessary for the new Image structure and returns a pointer to 76 % the new image. 77 % 78 % The format of the ReadSCRImage method is: 79 % 80 % Image *ReadSCRImage(const ImageInfo *image_info,ExceptionInfo *exception) 81 % 82 % A description of each parameter follows: 83 % 84 % o image_info: the image info. 85 % 86 % o exception: return any errors or warnings in this structure. 87 % 88 */ 89 static Image *ReadSCRImage(const ImageInfo *image_info,ExceptionInfo *exception) 90 { 91 char zxscr[6144]; 92 char zxattr[768]; 93 int octetnr; 94 int octetline; 95 int zoneline; 96 int zonenr; 97 int octet_val; 98 int attr_nr; 99 int pix; 100 int piy; 101 int binar[8]; 102 int attrbin[8]; 103 int *pbin; 104 int *abin; 105 int z; 106 int one_nr; 107 int ink; 108 int paper; 109 int bright; 110 111 unsigned char colour_palette[] = { 112 0, 0, 0, 113 0, 0,192, 114 192, 0, 0, 115 192, 0,192, 116 0,192, 0, 117 0,192,192, 118 192,192, 0, 119 192,192,192, 120 0, 0, 0, 121 0, 0,255, 122 255, 0, 0, 123 255, 0,255, 124 0,255, 0, 125 0,255,255, 126 255,255, 0, 127 255,255,255 128 }; 129 130 Image 131 *image; 132 133 MagickBooleanType 134 status; 135 136 register Quantum 137 *q; 138 139 ssize_t 140 count; 141 142 /* 143 Open image file. 144 */ 145 assert(image_info != (const ImageInfo *) NULL); 146 assert(image_info->signature == MagickCoreSignature); 147 if (image_info->debug != MagickFalse) 148 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 149 image_info->filename); 150 assert(exception != (ExceptionInfo *) NULL); 151 assert(exception->signature == MagickCoreSignature); 152 image=AcquireImage(image_info,exception); 153 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); 154 if (status == MagickFalse) 155 { 156 image=DestroyImageList(image); 157 return((Image *) NULL); 158 } 159 image->columns = 256; 160 image->rows = 192; 161 status=SetImageExtent(image,image->columns,image->rows,exception); 162 if (status == MagickFalse) 163 return(DestroyImageList(image)); 164 count=ReadBlob(image,6144,(unsigned char *) zxscr); 165 if (count != 6144) 166 ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 167 count=ReadBlob(image,768,(unsigned char *) zxattr); 168 if (count != 768) 169 ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 170 for(zonenr=0;zonenr<3;zonenr++) 171 { 172 for(zoneline=0;zoneline<8;zoneline++) 173 { 174 for(octetline=0;octetline<8;octetline++) 175 { 176 for(octetnr=(zoneline*32);octetnr<((zoneline*32)+32);octetnr++) 177 { 178 octet_val = zxscr[octetnr+(256*octetline)+(zonenr*2048)]; 179 attr_nr = zxattr[octetnr+(256*zonenr)]; 180 181 pix = (((8*octetnr)-(256*zoneline))); 182 piy = ((octetline+(8*zoneline)+(zonenr*64))); 183 184 pbin = binar; 185 abin = attrbin; 186 187 one_nr=1; 188 189 for(z=0;z<8;z++) 190 { 191 if(octet_val&one_nr) 192 { 193 *pbin = 1; 194 } else { 195 *pbin = 0; 196 } 197 one_nr=one_nr*2; 198 pbin++; 199 } 200 201 one_nr = 1; 202 203 for(z=0;z<8;z++) 204 { 205 if(attr_nr&one_nr) 206 { 207 *abin = 1; 208 } else { 209 *abin = 0; 210 } 211 one_nr=one_nr*2; 212 abin++; 213 } 214 215 ink = (attrbin[0]+(2*attrbin[1])+(4*attrbin[2])); 216 paper = (attrbin[3]+(2*attrbin[4])+(4*attrbin[5])); 217 bright = attrbin[6]; 218 219 if(bright) { ink=ink+8; paper=paper+8; } 220 221 for(z=7;z>-1;z--) 222 { 223 q=QueueAuthenticPixels(image,pix,piy,1,1,exception); 224 if (q == (Quantum *) NULL) 225 break; 226 227 if(binar[z]) 228 { 229 SetPixelRed(image,ScaleCharToQuantum( 230 colour_palette[3*ink]),q); 231 SetPixelGreen(image,ScaleCharToQuantum( 232 colour_palette[1+(3*ink)]),q); 233 SetPixelBlue(image,ScaleCharToQuantum( 234 colour_palette[2+(3*ink)]),q); 235 } else { 236 SetPixelRed(image,ScaleCharToQuantum( 237 colour_palette[3*paper]),q); 238 SetPixelGreen(image,ScaleCharToQuantum( 239 colour_palette[1+(3*paper)]),q); 240 SetPixelBlue(image,ScaleCharToQuantum( 241 colour_palette[2+(3*paper)]),q); 242 } 243 244 pix++; 245 } 246 } 247 } 248 } 249 } 250 (void) CloseBlob(image); 251 return(GetFirstImageInList(image)); 252 } 253 254 /* 256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 257 % % 258 % % 259 % % 260 % R e g i s t e r S C R I m a g e % 261 % % 262 % % 263 % % 264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 265 % 266 % RegisterSCRImage() adds attributes for the SCR image format to 267 % the list of supported formats. The attributes include the image format 268 % tag, a method to read and/or write the format, whether the format 269 % supports the saving of more than one frame to the same file or blob, 270 % whether the format supports native in-memory I/O, and a brief 271 % description of the format. 272 % 273 % The format of the RegisterSCRImage method is: 274 % 275 % size_t RegisterSCRImage(void) 276 % 277 */ 278 ModuleExport size_t RegisterSCRImage(void) 279 { 280 MagickInfo 281 *entry; 282 283 entry=AcquireMagickInfo("SCR","SCR","ZX-Spectrum SCREEN$"); 284 entry->decoder=(DecodeImageHandler *) ReadSCRImage; 285 entry->flags^=CoderAdjoinFlag; 286 (void) RegisterMagickInfo(entry); 287 return(MagickImageCoderSignature); 288 } 289 290 /* 292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 293 % % 294 % % 295 % % 296 % U n r e g i s t e r S C R I m a g e % 297 % % 298 % % 299 % % 300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 301 % 302 % UnregisterSCRImage() removes format registrations made by the 303 % SCR module from the list of supported formats. 304 % 305 % The format of the UnregisterSCRImage method is: 306 % 307 % UnregisterSCRImage(void) 308 % 309 */ 310 ModuleExport void UnregisterSCRImage(void) 311 { 312 (void) UnregisterMagickInfo("SCR"); 313 } 314