ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
images_storage.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#include "../../libs/msc1.h"
38
39/****************************************************************************
40 * CODE SECTION
41 ****************************************************************************/
42
49/* <usermanual>
50@keyword IMAGES (storage)
51
52@english
53The ''IMAGES'' command, inserted inside a ''BEGIN STORAGE'' - ''ENDSTORAGE'' block,
54allows you to define the content of the mass storage element as an set of images. The basic
55syntax requires indicating the name of the ''source'' file that will be converted
56and inserted into the medium. If you don't want to use the same name, you can indicate
57an alias (''AS target'').
58
59@italian
60Il comando ''IMAGES'', inserita all'interno di un blocco ''BEGIN STORAGE'' -
61''ENDSTORAGE'', permette di definire il contenuto dell'elemento di memorizzazione
62di massa come una serie di immagini. La sintassi di base prevede di indicare il nome del file
63sorgente che sarà convertito e inserito nel supporto. Se non si vuole utilizzare
64lo stesso nome, è possibile indicare un alias (''AS target'').
65
66@syntax IMAGES source [AS target] FRAME SIZE(width, height)
67
68@example IMAGES "examples/data.png" FRAME SIZE(16, 16)
69@example IMAGES "sprites.bmp" AS "sprites.dat" FRAME SIZE(16, 16)
70
71@usedInExample storage_example_03.bas
72
73@target all
74@verified
75</usermanual> */
76Variable * images_storage( Environment * _environment, char * _source_name, char * _target_name, int _mode, int _frame_width, int _frame_height, int _flags, int _transparent_color, int _background_color, int _bank_expansion, int _origin_x, int _origin_y, int _offset_x, int _offset_y ) {
77
78 file_storage( _environment, _source_name, _target_name, FSF_BINARY, 0 );
79
80 Variable * final = variable_temporary( _environment, VT_IMAGES, 0 );
81
82 AtlasDescriptor * atlasDescriptor = atlas_descriptor_create( _environment, _source_name, _flags, _origin_x, _origin_y, _frame_width, _frame_height, _offset_x, _offset_y );
83
84 int bufferSize = 0;
85 Variable * firstImage = NULL;
86 Variable * lastImage = NULL;
87
88 _environment->disableMemoryAreas = 1;
89
90 ImageDescriptor * frame = atlasDescriptor->frames;
91 for(int i=0; i<atlasDescriptor->count; ++i ) {
92 Variable * partial = image_converter( _environment, frame->data, frame->width, frame->height, frame->depth, 0, 0, frame->width, frame->height, _mode, _transparent_color, _flags );
93 if ( !firstImage && !lastImage ) {
94 firstImage = partial;
95 lastImage = firstImage;
96 } else {
97 lastImage->next = partial;
98 lastImage = lastImage->next;
99 }
100 bufferSize += partial->size;
101 frame = frame->next;
102 }
103
104 bufferSize += 3;
105
106 char * buffer = malloc( bufferSize );
107 char * ptr = buffer;
108 ptr[0] = atlasDescriptor->count;
109 ptr[1] = ( _frame_width & 0xff );
110 ptr[2] = ( _frame_width >> 8 ) & 0xff;
111
112 if ( ( firstImage->size * atlasDescriptor->count ) > 0xffff ) {
114 }
115
116 final->offsettingFrames = offsetting_size_count( _environment, firstImage->size, atlasDescriptor->count );
117 offsetting_add_variable_reference( _environment, final->offsettingFrames, final, 0 );
118
119 ptr += 3;
120 lastImage = firstImage;
121 for(int i=0; i<atlasDescriptor->count; ++i ) {
122 memcpy( ptr, lastImage->valueBuffer, lastImage->size );
123 ptr += lastImage->size;
124 lastImage = lastImage->next;
125 }
126 variable_store_buffer( _environment, final->name, buffer, bufferSize, 0 );
127
128 lastImage = firstImage;
129 for(int i=0; i<atlasDescriptor->count; ++i ) {
130 variable_temporary_remove( _environment, lastImage->name );
131 lastImage = lastImage->next;
132 }
133
134 _environment->disableMemoryAreas = 0;
135
136 // stbi_image_free(source);
137
138 if ( ( _flags & FLAG_COMPRESSED ) && !_environment->compressionForbidden ) {
139
140 // Try to compress the result of image conversion.
141 // This means that the buffer will be compressed using MSC1
142 // algorithm, up to 32 frequent sequences. The original size of
143 // the buffer will be considered as "uncompressed" size.
144 MSC1Compressor * compressor = msc1_create( 32 );
145 final->uncompressedSize = final->size;
146 MemoryBlock * output = msc1_compress( compressor, final->valueBuffer, final->uncompressedSize, &final->size );
147
148 int temporary;
149 MemoryBlock * outputCheck = msc1_uncompress( compressor, output, final->size, &temporary );
150 if ( memcmp( outputCheck, final->valueBuffer, final->uncompressedSize ) != 0 ) {
151 CRITICAL_COMPRESSION_FAILED(_source_name);
152 }
153 msc1_free( compressor );
154 // printf( "%s: %d bytes -> %d bytes\n", _filename, final->uncompressedSize, final->size );
155 // If the compressed memory is greater than the original
156 // size, we discard the compression and we will continue as
157 // usual.
158 if ( final->uncompressedSize < final->size ) {
159 final->size = final->uncompressedSize;
160 final->uncompressedSize = 0;
161 free( output );
162 }
163 // Otherwise, we can safely replace the original data
164 // buffer with the compressed one.
165 else {
166 free( final->valueBuffer );
167 final->valueBuffer = output;
168 }
169 final->residentAssigned = 1;
170 _environment->maxExpansionBankSize[1] = BANK_SIZE;
171
172 }
173
174 lastImage = firstImage;
175 for(int i=0; i<atlasDescriptor->count; ++i ) {
176 variable_temporary_remove( _environment, lastImage->name );
177 lastImage = lastImage->next;
178 }
179
180 _environment->currentFileStorage->size = final->size;
181 _environment->currentFileStorage->content = final->valueBuffer;
182
183 return final;
184
185}
void variable_temporary_remove(Environment *_environment, char *_name)
void offsetting_add_variable_reference(Environment *_environment, Offsetting *_first, Variable *_var, int _sequence)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
Offsetting * offsetting_size_count(Environment *_environment, int _size, int _count)
Variable * variable_store_buffer(Environment *_environment, char *_destination, unsigned char *_buffer, int _size, int _at)
Variable * image_converter(Environment *_environment, char *_data, int _width, int _height, int _depth, int _offset_x, int _offset_y, int _frame_width, int _frame_height, int _mode, int _transparent_color, int _flags)
#define BANK_SIZE
Definition atari.h:146
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)
void file_storage(Environment *_environment, char *_source_name, char *_target_name, FileStorageFormat _format, VariableType _type)
Emit code for FILE ... AS ....
Variable * images_storage(Environment *_environment, char *_source_name, char *_target_name, int _mode, int _frame_width, int _frame_height, int _flags, int _transparent_color, int _background_color, int _bank_expansion, int _origin_x, int _origin_y, int _offset_x, int _offset_y)
Emit code for IMAGE ... AS ....
MSC1Compressor * msc1_create(int _maximum_repeated_sequences)
Definition msc1.c:300
void msc1_free(MSC1Compressor *_msc1)
Definition msc1.c:740
MemoryBlock * msc1_uncompress(MSC1Compressor *_msc1, MemoryBlock *_input, int _size, int *_output_size)
Definition msc1.c:746
MemoryBlock * msc1_compress(MSC1Compressor *_msc1, MemoryBlock *_input, int _size, int *_output_size)
Definition msc1.c:381
unsigned char MemoryBlock
Definition msc1.h:90
struct _MSC1Compressor MSC1Compressor
struct _ImageDescriptor * frames
Definition ugbc.h:939
int disableMemoryAreas
Definition ugbc.h:2691
int compressionForbidden
Definition ugbc.h:3169
int maxExpansionBankSize[MAX_RESIDENT_SHAREDS]
Definition ugbc.h:3010
FileStorage * currentFileStorage
Definition ugbc.h:2536
int size
Definition ugbc.h:204
char * content
Definition ugbc.h:210
char * data
Definition ugbc.h:911
struct _ImageDescriptor * next
Definition ugbc.h:919
unsigned char * valueBuffer
Definition ugbc.h:1061
struct _Variable * next
Definition ugbc.h:1225
int size
Definition ugbc.h:1077
char * name
Definition ugbc.h:979
void * malloc(YYSIZE_T)
void free(void *)
#define FLAG_COMPRESSED
Definition ugbc.h:4570
struct _ImageDescriptor ImageDescriptor
@ FSF_BINARY
Definition ugbc.h:251
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
#define CRITICAL_IMAGES_LOAD_IMAGE_TOO_BIG(v)
Definition ugbc.h:3662
@ VT_IMAGES
Definition ugbc.h:495
struct _AtlasDescriptor AtlasDescriptor
#define CRITICAL_COMPRESSION_FAILED(v)
Definition ugbc.h:3768