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-2016 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%    http://www.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/*
40  Include declarations.
41*/
42#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
45#include "MagickCore/cache.h"
46#include "MagickCore/exception.h"
47#include "MagickCore/exception-private.h"
48#include "MagickCore/image.h"
49#include "MagickCore/image-private.h"
50#include "MagickCore/list.h"
51#include "MagickCore/magick.h"
52#include "MagickCore/memory_.h"
53#include "MagickCore/monitor.h"
54#include "MagickCore/monitor-private.h"
55#include "MagickCore/pixel-accessor.h"
56#include "MagickCore/quantum-private.h"
57#include "MagickCore/static.h"
58#include "MagickCore/string_.h"
59#include "MagickCore/module.h"
60
61/*
62%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63%                                                                             %
64%                                                                             %
65%                                                                             %
66%   R e a d S C R I m a g e                                                   %
67%                                                                             %
68%                                                                             %
69%                                                                             %
70%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71%
72%  ReadSCRImage() reads a Scitex image file and returns it.  It allocates
73%  the memory necessary for the new Image structure and returns a pointer to
74%  the new image.
75%
76%  The format of the ReadSCRImage method is:
77%
78%      Image *ReadSCRImage(const ImageInfo *image_info,ExceptionInfo *exception)
79%
80%  A description of each parameter follows:
81%
82%    o image_info: the image info.
83%
84%    o exception: return any errors or warnings in this structure.
85%
86*/
87static Image *ReadSCRImage(const ImageInfo *image_info,ExceptionInfo *exception)
88{
89    char zxscr[6144];
90    char zxattr[768];
91    int octetnr;
92    int octetline;
93    int zoneline;
94    int zonenr;
95    int octet_val;
96    int attr_nr;
97    int pix;
98    int piy;
99    int binar[8];
100    int attrbin[8];
101    int *pbin;
102    int *abin;
103    int z;
104    int one_nr;
105    int ink;
106    int paper;
107    int bright;
108
109  unsigned char colour_palette[] = {
110      0,  0,  0,
111      0,  0,192,
112    192,  0,  0,
113    192,  0,192,
114      0,192,  0,
115      0,192,192,
116    192,192,  0,
117    192,192,192,
118      0,  0,  0,
119      0,  0,255,
120    255,  0,  0,
121    255,  0,255,
122      0,255,  0,
123      0,255,255,
124    255,255,  0,
125    255,255,255
126  };
127
128  Image
129    *image;
130
131  MagickBooleanType
132    status;
133
134  register Quantum
135    *q;
136
137  ssize_t
138    count;
139
140  /*
141    Open image file.
142  */
143  assert(image_info != (const ImageInfo *) NULL);
144  assert(image_info->signature == MagickCoreSignature);
145  if (image_info->debug != MagickFalse)
146    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
147      image_info->filename);
148  assert(exception != (ExceptionInfo *) NULL);
149  assert(exception->signature == MagickCoreSignature);
150  image=AcquireImage(image_info,exception);
151  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
152  if (status == MagickFalse)
153    {
154      image=DestroyImageList(image);
155      return((Image *) NULL);
156    }
157  image->columns = 256;
158  image->rows = 192;
159  status=SetImageExtent(image,image->columns,image->rows,exception);
160  if (status == MagickFalse)
161    return(DestroyImageList(image));
162  count=ReadBlob(image,6144,(unsigned char *) zxscr);
163  (void) count;
164  count=ReadBlob(image,768,(unsigned char *) zxattr);
165  for(zonenr=0;zonenr<3;zonenr++)
166  {
167      for(zoneline=0;zoneline<8;zoneline++)
168        {
169        for(octetline=0;octetline<8;octetline++)
170      {
171          for(octetnr=(zoneline*32);octetnr<((zoneline*32)+32);octetnr++)
172            {
173            octet_val = zxscr[octetnr+(256*octetline)+(zonenr*2048)];
174            attr_nr = zxattr[octetnr+(256*zonenr)];
175
176            pix = (((8*octetnr)-(256*zoneline)));
177            piy = ((octetline+(8*zoneline)+(zonenr*64)));
178
179            pbin = binar;
180            abin = attrbin;
181
182            one_nr=1;
183
184            for(z=0;z<8;z++)
185          {
186              if(octet_val&one_nr)
187            {
188                *pbin = 1;
189            } else {
190                *pbin = 0;
191            }
192              one_nr=one_nr*2;
193              pbin++;
194          }
195
196            one_nr = 1;
197
198            for(z=0;z<8;z++)
199          {
200              if(attr_nr&one_nr)
201            {
202                *abin = 1;
203            } else {
204                *abin = 0;
205            }
206              one_nr=one_nr*2;
207              abin++;
208          }
209
210            ink = (attrbin[0]+(2*attrbin[1])+(4*attrbin[2]));
211            paper = (attrbin[3]+(2*attrbin[4])+(4*attrbin[5]));
212            bright = attrbin[6];
213
214            if(bright) { ink=ink+8; paper=paper+8; }
215
216            for(z=7;z>-1;z--)
217          {
218              q=QueueAuthenticPixels(image,pix,piy,1,1,exception);
219              if (q == (Quantum *) NULL)
220                break;
221
222              if(binar[z])
223            {
224                SetPixelRed(image,ScaleCharToQuantum(
225                  colour_palette[3*ink]),q);
226                SetPixelGreen(image,ScaleCharToQuantum(
227                  colour_palette[1+(3*ink)]),q);
228                SetPixelBlue(image,ScaleCharToQuantum(
229                  colour_palette[2+(3*ink)]),q);
230            } else {
231                SetPixelRed(image,ScaleCharToQuantum(
232                  colour_palette[3*paper]),q);
233                SetPixelGreen(image,ScaleCharToQuantum(
234                  colour_palette[1+(3*paper)]),q);
235                SetPixelBlue(image,ScaleCharToQuantum(
236                  colour_palette[2+(3*paper)]),q);
237            }
238
239              pix++;
240          }
241        }
242      }
243    }
244  }
245  (void) CloseBlob(image);
246  return(GetFirstImageInList(image));
247}
248
249/*
250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251%                                                                             %
252%                                                                             %
253%                                                                             %
254%   R e g i s t e r S C R I m a g e                                           %
255%                                                                             %
256%                                                                             %
257%                                                                             %
258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
259%
260%  RegisterSCRImage() adds attributes for the SCR image format to
261%  the list of supported formats.  The attributes include the image format
262%  tag, a method to read and/or write the format, whether the format
263%  supports the saving of more than one frame to the same file or blob,
264%  whether the format supports native in-memory I/O, and a brief
265%  description of the format.
266%
267%  The format of the RegisterSCRImage method is:
268%
269%      size_t RegisterSCRImage(void)
270%
271*/
272ModuleExport size_t RegisterSCRImage(void)
273{
274  MagickInfo
275    *entry;
276
277  entry=AcquireMagickInfo("SCR","SCR","ZX-Spectrum SCREEN$");
278  entry->decoder=(DecodeImageHandler *) ReadSCRImage;
279  entry->flags^=CoderAdjoinFlag;
280  (void) RegisterMagickInfo(entry);
281  return(MagickImageCoderSignature);
282}
283
284/*
285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286%                                                                             %
287%                                                                             %
288%                                                                             %
289%   U n r e g i s t e r S C R I m a g e                                       %
290%                                                                             %
291%                                                                             %
292%                                                                             %
293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294%
295%  UnregisterSCRImage() removes format registrations made by the
296%  SCR module from the list of supported formats.
297%
298%  The format of the UnregisterSCRImage method is:
299%
300%      UnregisterSCRImage(void)
301%
302*/
303ModuleExport void UnregisterSCRImage(void)
304{
305  (void) UnregisterMagickInfo("SCR");
306}
307