Fix missing translation
[geeqie.git] / src / image-load-zxscr.cc
1 /*
2  * Copyright (C) 2021 - The Geeqie Team
3  *
4  * Author: Dusan Gallo
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #include "image-load-zxscr.h"
22
23 #include <config.h>
24
25 #include "debug.h"
26 #include "image-load.h"
27
28 struct ImageLoaderZXSCR {
29         ImageLoaderBackendCbAreaUpdated area_updated_cb;
30         ImageLoaderBackendCbSize size_cb;
31         ImageLoaderBackendCbAreaPrepared area_prepared_cb;
32         gpointer data;
33         GdkPixbuf *pixbuf;
34         guint requested_width;
35         guint requested_height;
36         gboolean abort;
37 };
38
39 const guchar palette[2][8][3] = {
40         {
41                 {0x00, 0x00, 0x00},
42                 {0x00, 0x00, 0xbf},
43                 {0xbf, 0x00, 0x00},
44                 {0xbf, 0x00, 0xbf},
45                 {0x00, 0xbf, 0x00},
46                 {0x00, 0xbf, 0xbf},
47                 {0xbf, 0xbf, 0x00},
48                 {0xbf, 0xbf, 0xbf}
49         }, {
50                 {0x00, 0x00, 0x00},
51                 {0x00, 0x00, 0xff},
52                 {0xff, 0x00, 0x00},
53                 {0xff, 0x00, 0xff},
54                 {0x00, 0xff, 0x00},
55                 {0x00, 0xff, 0xff},
56                 {0xff, 0xff, 0x00},
57                 {0xff, 0xff, 0xff}
58         }
59 };
60
61 static void free_buffer(guchar *pixels, gpointer)
62 {
63         g_free(pixels);
64 }
65
66 static gboolean image_loader_zxscr_load(gpointer loader, const guchar *buf, gsize count, GError **)
67 {
68         auto ld = static_cast<ImageLoaderZXSCR *>(loader);
69         guint8 *pixels;
70         gint width;
71         gint height;
72         gint row;
73         gint col;
74         gint mrow;
75         gint pxs;
76         gint i;
77         guint8 attr;
78         guint8 bright;
79         guint8 ink;
80         guint8 paper;
81         guint8 *ptr;
82
83         if (count != 6144 && count != 6912)
84                 {
85                 log_printf("Error: zxscr reader error\n");
86                 return FALSE;
87                 }
88
89         width = 256;
90         height = 192;
91
92         pixels = static_cast<guint8 *>(g_try_malloc(width * height * 3));
93
94         if (!pixels)
95                 {
96                 log_printf("Error: zxscr reader error\n");
97                 return FALSE;
98                 }
99
100         ld->pixbuf = gdk_pixbuf_new_from_data(pixels, GDK_COLORSPACE_RGB, FALSE, 8, width, height, width * 3, free_buffer, nullptr);
101
102         if (!ld->pixbuf)
103                 {
104                 g_free(pixels);
105                 DEBUG_1("Insufficient memory to open ZXSCR file");
106                 return FALSE;
107                 }
108         //let's decode screen
109         for (row = 0; row < 24; row++)
110                 for (col = 0; col < 32; col++)
111                         {
112                         if (count == 6144)
113                                 {
114                                 //if we have pixels only, make default white ink on black paper
115                                 bright = 0x01;
116                                 ink = 0x07;
117                                 paper = 0x00;
118                                 }
119                         else
120                                 {
121                                 attr = buf[6144 + row * 32 + col];
122                                 bright = (attr >> 6) & 0x01;
123                                 ink = attr & 0x07;
124                                 paper = ((attr >> 3) & 0x07);
125                                 }
126                         ptr = pixels + (row * 256 + col) * 8 * 3;
127
128                         for (mrow = 0; mrow < 8; mrow ++)
129                                 {
130                                 pxs = buf[(row / 8) * 2048 + mrow * 256 + (row % 8) * 32 + col];
131                                 for (i = 0; i < 8; i++)
132                                         {
133                                         if (pxs & 0x80)
134                                                 {
135                                                 *ptr++ = palette[bright][ink][0];       //r
136                                                 *ptr++ = palette[bright][ink][1];       //g
137                                                 *ptr++ = palette[bright][ink][2];       //b
138                                                 }
139                                         else
140                                                 {
141                                                 *ptr++ = palette[bright][paper][0];
142                                                 *ptr++ = palette[bright][paper][1];
143                                                 *ptr++ = palette[bright][paper][2];
144                                                 }
145                                         pxs <<= 1;
146                                         }
147                                 ptr += (31 * 8 * 3);
148                                 }
149                         }
150
151         ld->area_updated_cb(loader, 0, 0, width, height, ld->data);
152
153         return TRUE;
154 }
155
156 static gpointer image_loader_zxscr_new(ImageLoaderBackendCbAreaUpdated area_updated_cb, ImageLoaderBackendCbSize size_cb, ImageLoaderBackendCbAreaPrepared area_prepared_cb, gpointer data)
157 {
158         auto loader = g_new0(ImageLoaderZXSCR, 1);
159         loader->area_updated_cb = area_updated_cb;
160         loader->size_cb = size_cb;
161         loader->area_prepared_cb = area_prepared_cb;
162         loader->data = data;
163         return loader;
164 }
165
166 static void image_loader_zxscr_set_size(gpointer loader, int width, int height)
167 {
168         auto ld = static_cast<ImageLoaderZXSCR *>(loader);
169         ld->requested_width = width;
170         ld->requested_height = height;
171 }
172
173 static GdkPixbuf *image_loader_zxscr_get_pixbuf(gpointer loader)
174 {
175         auto ld = static_cast<ImageLoaderZXSCR *>(loader);
176         return ld->pixbuf;
177 }
178
179 static gchar *image_loader_zxscr_get_format_name(gpointer)
180 {
181         return g_strdup("zxscr");
182 }
183
184 static gchar **image_loader_zxscr_get_format_mime_types(gpointer)
185 {
186         static const gchar *mime[] = {"application/octet-stream", nullptr};
187         return g_strdupv(const_cast<gchar **>(mime));
188 }
189
190 static gboolean image_loader_zxscr_close(gpointer, GError **)
191 {
192         return TRUE;
193 }
194
195 static void image_loader_zxscr_abort(gpointer loader)
196 {
197         auto ld = static_cast<ImageLoaderZXSCR *>(loader);
198         ld->abort = TRUE;
199 }
200
201 static void image_loader_zxscr_free(gpointer loader)
202 {
203         auto ld = static_cast<ImageLoaderZXSCR *>(loader);
204         if (ld->pixbuf) g_object_unref(ld->pixbuf);
205         g_free(ld);
206 }
207
208 void image_loader_backend_set_zxscr(ImageLoaderBackend *funcs)
209 {
210         funcs->loader_new = image_loader_zxscr_new;
211         funcs->set_size = image_loader_zxscr_set_size;
212         funcs->load = image_loader_zxscr_load;
213         funcs->write = nullptr;
214         funcs->get_pixbuf = image_loader_zxscr_get_pixbuf;
215         funcs->close = image_loader_zxscr_close;
216         funcs->abort = image_loader_zxscr_abort;
217         funcs->free = image_loader_zxscr_free;
218         funcs->get_format_name = image_loader_zxscr_get_format_name;
219         funcs->get_format_mime_types = image_loader_zxscr_get_format_mime_types;
220 }
221 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */