ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
image_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 IMAGE (storage)
51
52@english
53The ''IMAGE'' command, inserted inside a ''BEGIN STORAGE'' - ''ENDSTORAGE'' block,
54allows you to define the content of the mass storage element as an image. 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 ''IMAGE'', inserita all'interno di un blocco ''BEGIN STORAGE'' -
61''ENDSTORAGE'', permette di definire il contenuto dell'elemento di memorizzazione
62di massa come "immagine". 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 IMAGE source [AS target]
67
68@example IMAGE "examples/data.png"
69@example IMAGE "sprites.bmp" AS "sprites.dat"
70
71@usedInExample storage_example_02.bas
72
73@target all
74@verified
75</usermanual> */
76Variable * image_storage( Environment * _environment, char * _source_name, char * _target_name, int _mode, int _flags, int _transparent_color, int _background_color, int _bank_expansion ) {
77
78 file_storage( _environment, _source_name, _target_name, FSF_BINARY, 0 );
79
80 // No we are going to load the image from the PC.
81 // Those variables will maintain the data of the original image.
82
83 ImageDescriptor * imageDescriptor = image_descriptor_create( _environment, _source_name, _flags );
84
85 // This is a workaround. In a previous release of ugBASIC, we must give
86 // the color index to be used as transparency. If given, we active the
87 // "FLAG TRANSPARENCY" during the conversion.
88 if ( _transparent_color != -1 ) {
89 _flags |= FLAG_TRANSPARENCY;
90 }
91
92 // Now we are able to convert the image from the original format to the
93 // custom format of the target. This is a time efficient mode to store
94 // the image, but not a space efficient (no compression is done).
95 // Space efficiency can be applied after, if a bank is present.
96 Variable * result = image_converter( _environment, imageDescriptor->data, imageDescriptor->width, imageDescriptor->height, imageDescriptor->depth, 0, 0, 0, 0, _mode, _transparent_color, _flags );
97
98 if ( ( _flags & FLAG_COMPRESSED ) && !_environment->compressionForbidden ) {
99
100 // Try to compress the result of image conversion.
101 // This means that the buffer will be compressed using MSC1
102 // algorithm, up to 32 frequent sequences. The original size of
103 // the buffer will be considered as "uncompressed" size.
104 MSC1Compressor * compressor = msc1_create( 32 );
105 result->uncompressedSize = result->size;
106 MemoryBlock * output = msc1_compress( compressor, result->valueBuffer, result->uncompressedSize, &result->size );
107
108 int temporary;
109 MemoryBlock * outputCheck = msc1_uncompress( compressor, output, result->size, &temporary );
110 if ( memcmp( outputCheck, result->valueBuffer, result->uncompressedSize ) != 0 ) {
111 CRITICAL_COMPRESSION_FAILED(_source_name);
112 }
113 msc1_free( compressor );
114
115 // If the compressed memory is greater than the original
116 // size, we discard the compression and we will continue as
117 // usual.
118 if ( result->uncompressedSize < result->size ) {
119 result->size = result->uncompressedSize;
120 result->uncompressedSize = 0;
121 free( output );
122 }
123 // Otherwise, we can safely replace the original data
124 // buffer with the compressed one.
125 else {
126 free( result->valueBuffer );
127 result->valueBuffer = output;
128 }
129 result->residentAssigned = 1;
130 _environment->maxExpansionBankSize[1] = BANK_SIZE;
131
132 }
133
134 _environment->currentFileStorage->size = result->size;
135 _environment->currentFileStorage->content = result->valueBuffer;
136
137 return result;
138
139}
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
void file_storage(Environment *_environment, char *_source_name, char *_target_name, FileStorageFormat _format, VariableType _type)
Emit code for FILE ... AS ....
ImageDescriptor * image_descriptor_create(Environment *_environment, char *_filename, int _flags)
Variable * image_storage(Environment *_environment, char *_source_name, char *_target_name, int _mode, int _flags, int _transparent_color, int _background_color, int _bank_expansion)
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
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
unsigned char * valueBuffer
Definition ugbc.h:1061
int residentAssigned
Definition ugbc.h:1175
int size
Definition ugbc.h:1077
int uncompressedSize
Definition ugbc.h:1082
void free(void *)
#define FLAG_COMPRESSED
Definition ugbc.h:4570
struct _ImageDescriptor ImageDescriptor
@ FSF_BINARY
Definition ugbc.h:251
#define FLAG_TRANSPARENCY
Definition ugbc.h:4567
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
#define CRITICAL_COMPRESSION_FAILED(v)
Definition ugbc.h:3768