ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
atlas_descriptor_create.c
Go to the documentation of this file.
1/*****************************************************************************
2 * ugBASIC - an isomorphic BASIC language compiler for retrocomputers *
3 *****************************************************************************
4 * Copyright 2021-2026 Marco Spedaletti (asimov@mclink.it)
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *----------------------------------------------------------------------------
18 * Concesso in licenza secondo i termini della Licenza Apache, versione 2.0
19 * (la "Licenza"); è proibito usare questo file se non in conformità alla
20 * Licenza. Una copia della Licenza è disponibile all'indirizzo:
21 *
22 * http://www.apache.org/licenses/LICENSE-2.0
23 *
24 * Se non richiesto dalla legislazione vigente o concordato per iscritto,
25 * il software distribuito nei termini della Licenza è distribuito
26 * "COSÌ COM'È", SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO, esplicite o
27 * implicite. Consultare la Licenza per il testo specifico che regola le
28 * autorizzazioni e le limitazioni previste dalla medesima.
29 ****************************************************************************/
30
31/****************************************************************************
32 * INCLUDE SECTION
33 ****************************************************************************/
34
35#include "../../ugbc.h"
37
38/****************************************************************************
39 * CODE SECTION
40 ****************************************************************************/
41
42static ImageDescriptor * cut_frame_from_atlas( Environment * _environment, AtlasDescriptor * _atlas, int _x, int _y ) {
43
44 ImageDescriptor * frame = malloc( sizeof( ImageDescriptor ) );
45 memset( frame, 0, sizeof( ImageDescriptor ) );
46
47 frame->width = _atlas->frameWidth;
48 frame->height = _atlas->frameHeight;
49 frame->depth = _atlas->image->depth;
50
51 frame->size = frame->width * frame->height * frame->depth;
52
53 frame->data = malloc( frame->size );
54 memset( frame->data, 0, frame->size );
55
56 frame->colors = malloc( sizeof( RGBi ) * frame->colorsCount );
57 memcpy( frame->colors, _atlas->image->colors, sizeof( RGBi ) * frame->colorsCount );
58 frame->colorsCount = _atlas->image->colorsCount;
59
60 char * source = _atlas->image->data +
61 ( _atlas->originX * _atlas->image->depth ) +
62 ( _atlas->originY * _atlas->image->width * _atlas->image->depth ) +
63 ( ( _atlas->frameWidth + _atlas->offsetX ) * _atlas->image->depth * _x ) +
64 ( ( _atlas->frameHeight + _atlas->offsetY ) * _atlas->image->width * _atlas->image->depth * _y );
65
66 char * destination = frame->data;
67
68 int frameHeight = frame->height;
69
70 while( frameHeight ) {
71 memcpy( destination, source, frame->width * frame->depth );
72 source += _atlas->image->width * frame->depth;
73 destination += frame->width * frame->depth;
74 --frameHeight;
75 }
76
77 return frame;
78
79}
80
81static ImageDescriptor * cut_frame_from_atlas_gif( Environment * _environment, AtlasDescriptor * _atlas, int _y ) {
82
83 ImageDescriptor * frame = malloc( sizeof( ImageDescriptor ) );
84 memset( frame, 0, sizeof( ImageDescriptor ) );
85
86 frame->size = _atlas->frameWidth * _atlas->frameHeight * _atlas->image->depth;
87
88 frame->data = malloc( frame->size );
89 memset( frame->data, 0, frame->size );
90
91 frame->width = _atlas->frameWidth;
92 frame->height = _atlas->frameWidth;
93 frame->depth = _atlas->image->depth;
94
95 frame->colors = malloc( sizeof( RGBi ) * frame->colorsCount );
96 memcpy( frame->colors, _atlas->image->colors, sizeof( RGBi ) * frame->colorsCount );
97 frame->colorsCount = _atlas->image->colorsCount;
98
99 char * source = _atlas->image->data +
100 ( _atlas->originX * _atlas->image->depth ) +
101 ( _atlas->originY * _atlas->image->width * _atlas->image->depth ) +
102 ( ( ( _atlas->frameHeight + _atlas->offsetY ) * _atlas->image->width * _atlas->image->depth + 2 ) * _y );
103
104 char * destination = frame->data;
105
106 int frameHeight = frame->height;
107
108 while( frameHeight ) {
109 memcpy( destination, source, frame->width * frame->depth );
110 source += frame->width * frame->depth;
111 destination += frame->width * frame->depth;
112 --frameHeight;
113 }
114
115 return frame;
116
117}
118
119AtlasDescriptor * atlas_descriptor_create( Environment * _environment, char * _filename, int _flags, int _image_origin_x, int _image_origin_y, int _frame_width, int _frame_height, int _frame_offset_x, int _frame_offset_y ) {
120
121 AtlasDescriptor * result = malloc( sizeof( AtlasDescriptor ) );
122 memset( result, 0, sizeof( AtlasDescriptor ) );
123
124 result->originX = _image_origin_x;
125 result->originY = _image_origin_y;
126 result->offsetX = _frame_offset_x;
127 result->offsetY = _frame_offset_y;
128
129 result->image = malloc( sizeof( ImageDescriptor ) );
130 memset( result->image, 0, sizeof( ImageDescriptor ) );
131
132 char * lookedFilename = resource_load_asserts( _environment, _filename );
133
134 result->image->fileSize = file_get_size( _environment, lookedFilename );
135
136 result->count = 0;
137 int layout_mode = 0;
138
139 if ( stbi_is_animated_gif( lookedFilename ) ) {
140 if ( _image_origin_x || _image_origin_y ) {
142 }
143 if ( _frame_offset_x || _frame_offset_y ) {
145 }
146 result->image->data = stbi_xload(lookedFilename, &result->image->width, &result->image->height, &result->count);
147 result->image->depth = 4;
148 result->frameWidth = result->image->width;
149 if ( ! result->frameWidth ) {
150 CRITICAL_INVALID_FRAME_WIDTH( _filename );
151 }
152 result->frameHeight = result->image->height;
153 if ( ! result->frameHeight ) {
155 }
156 result->horizontal = 1;
157 result->vertical = result->count;
158 layout_mode = 1;
159 } else {
160 if ( _frame_height < 0 || _frame_width < 0 ) {
162 }
163 result->image->data = stbi_load(lookedFilename, &result->image->width, &result->image->height, &result->image->depth, 0);
164 result->count = 0;
165 result->frameWidth = _frame_width;
166 result->frameHeight = _frame_height;
167 result->horizontal = 0; // ( ( result->image->width - result->originX) / (result->frameWidth+result->offsetX) ) + 1;
168 int w = result->image->width - result->originX;
169 while ( w >= result->frameWidth ) {
170 ++result->horizontal;
171 w -= result->frameWidth;
172 w -= result->offsetX;
173 }
174 result->vertical = 0 ; // ( ( result->image->height - result->originY) / (result->frameHeight+result->offsetY) );
175 int h = result->image->height - result->originY;
176 while ( h >= result->frameHeight ) {
177 ++result->vertical;
178 h -= result->frameHeight;
179 h -= result->offsetY;
180 }
181 layout_mode = 0;
182 }
183
184 if ( !result->image->data ) {
186 }
187
188 result->image->size = result->image->width * result->image->height * result->image->depth;
190 result->image->colorsCount = MAX_PALETTE;
191 result->image->colorsCount = rgbi_extract_palette( _environment, result->image->data, result->image->width, result->image->height, result->image->depth, result->image->colors, result->image->colorsCount, 1 );
192
193 result->count = result->horizontal * result->vertical;
194
195 adiline3("BMP:%4.4x:%4.4x:%2.2x", _frame_width, _frame_height, BITMAP_MODE_STANDARD );
196
197 if ( layout_mode == 0 ) {
198
199 int a = 1;
200
201 int i,di,x=0,y=0,z=0;
202
203 if( _flags & FLAG_ROLL_X ) {
204 a = (result->frameWidth - 1);
205 }
206
207 i = 0;
208 di = 1;
209
210 adiline5("LIS:%s:%s:%2.2x:%2.2x:%x", _filename, lookedFilename, result->count, result->horizontal, result->image->fileSize );
211
212 if( _flags & FLAG_FLIP_X ) {
213 result->image = image_descriptor_flip_x( _environment, result->image );
214 }
215
216 if( _flags & FLAG_FLIP_Y ) {
217 result->image = image_descriptor_flip_y( _environment, result->image );
218 }
219
220 // if ( _transparent_color != -1 ) {
221 // _flags |= FLAG_TRANSPARENCY;
222 // }
223
224 for( z=0; z<a; ++z ) {
225 for( y=0; y<result->vertical; ++y ) {
226 for( x=0; x<result->horizontal; ++x ) {
227 ImageDescriptor * frame = cut_frame_from_atlas( _environment, result, x, y );
228 if ( result->frames ) {
229 ImageDescriptor * actual = result->frames;
230 while( actual->next ) {
231 actual = actual->next;
232 };
233 actual->next = frame;
234 } else {
235 result->frames = frame;
236 }
237 i += di;
238 }
239 }
240 if( _flags & FLAG_ROLL_X ) {
241 if ( _flags & FLAG_FLIP_X ) {
242 result->image = image_descriptor_roll_x_left( _environment, result->image );
243 } else {
244 result->image = image_descriptor_roll_x_right( _environment, result->image );
245 }
246 }
247 }
248
249 } else {
250
251 int z;
252
253 adiline5("LIS:%s:%s:%2.2x:%2.2x:%x", _filename, lookedFilename, result->count, result->horizontal, result->image->fileSize );
254
255 // if( _flags & FLAG_FLIP_X ) {
256 // source = image_flip_x( _environment, source, width, height, depth );
257 // }
258 // if( _flags & FLAG_FLIP_Y ) {
259 // source = image_flip_y( _environment, source, width, height, depth );
260 // }
261
262 // if ( _transparent_color != -1 ) {
263 // _flags |= FLAG_TRANSPARENCY;
264 // }
265
266 for( z=0; z<result->count; ++z ) {
267 ImageDescriptor * frame = cut_frame_from_atlas_gif( _environment, result, z );
268 if ( result->frames ) {
269 ImageDescriptor * actual = result->frames;
270 while( actual->next ) {
271 actual = actual->next;
272 };
273 actual->next = frame;
274 } else {
275 result->frames = frame;
276 }
277 }
278
279 }
280
281 return result;
282
283}
#define BITMAP_MODE_STANDARD
Definition 6847.h:96
RGBi * malloc_palette(int _size)
Allocate a palette space.
char * resource_load_asserts(Environment *_environment, char *_filename)
int rgbi_extract_palette(Environment *_environment, unsigned char *_source, int _width, int _height, int _depth, RGBi _palette[], int _palette_size, int _sorted)
Extract the color palette from the given image.
int file_get_size(Environment *_environment, char *_filename)
AtlasDescriptor * atlas_descriptor_create(Environment *_environment, char *_filename, int _flags, int _image_origin_x, int _image_origin_y, int _frame_width, int _frame_height, int _frame_offset_x, int _frame_offset_y)
ImageDescriptor * image_descriptor_flip_x(Environment *_environment, ImageDescriptor *_source_image)
ImageDescriptor * image_descriptor_flip_y(Environment *_environment, ImageDescriptor *_source_image)
ImageDescriptor * image_descriptor_roll_x_left(Environment *_environment, ImageDescriptor *_source_image)
ImageDescriptor * image_descriptor_roll_x_right(Environment *_environment, ImageDescriptor *_source_image)
STBIDEF unsigned char * stbi_xload(char const *filename, int *x, int *y, int *frames)
Definition stb_image.c:58
STBIDEF int stbi_is_animated_gif(char const *filename)
Definition stb_image.c:15
STBIDEF stbi_uc * stbi_load(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels)
struct _ImageDescriptor * frames
Definition ugbc.h:939
struct _ImageDescriptor * image
Definition ugbc.h:925
int frameHeight
Definition ugbc.h:928
int colorsCount
Definition ugbc.h:918
RGBi * colors
Definition ugbc.h:917
char * data
Definition ugbc.h:911
struct _ImageDescriptor * next
Definition ugbc.h:919
void * malloc(YYSIZE_T)
#define CRITICAL_INVALID_FRAME_WIDTH(s)
Definition ugbc.h:3851
struct _ImageDescriptor ImageDescriptor
struct _RGBi RGBi
Structure to store color components (red, green and blue).
#define CRITICAL_IMAGES_LOAD_INVALID_AUTO_WITHOUT_GIF(v)
Definition ugbc.h:3661
#define CRITICAL_IMAGE_LOAD_UNKNOWN_FORMAT(f)
Definition ugbc.h:3501
struct _Environment Environment
Structure of compilation environment.
#define adiline5(s, a, b, c, d, e)
Definition ugbc.h:4207
#define FLAG_FLIP_X
Definition ugbc.h:4553
#define adiline3(s, a, b, c)
Definition ugbc.h:4197
struct _AtlasDescriptor AtlasDescriptor
#define CRITICAL_INVALID_FRAME_HEIGHT(s)
Definition ugbc.h:3852
#define MAX_PALETTE
Definition ugbc.h:568
#define CRITICAL_IMAGES_LOAD_INVALID_ORIGIN_WITH_GIF(f)
Definition ugbc.h:3737
#define FLAG_FLIP_Y
Definition ugbc.h:4554
#define FLAG_ROLL_X
Definition ugbc.h:4555
#define CRITICAL_IMAGES_LOAD_INVALID_OFFSET_WITH_GIF(f)
Definition ugbc.h:3738