Subversion Repositories Kolibri OS

Rev

Rev 8013 | Rev 8382 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3107 leency 1
//Asper
5598 pavelyakov 2
#ifndef INCLUDE_LIBIMG_H
3
#define INCLUDE_LIBIMG_H
3107 leency 4
 
5598 pavelyakov 5
#ifndef INCLUDE_KOLIBRI_H
6
#include "../lib/kolibri.h"
7
#endif
8
 
9
#ifndef INCLUDE_MEM_H
10
#include "../lib/mem.h"
11
#endif
12
 
13
#ifndef INCLUDE_DLL_H
14
#include "../lib/dll.h"
15
#endif
16
 
3107 leency 17
//library
18
dword libimg = #alibimg;
7252 leency 19
char alibimg[] = "/sys/lib/libimg.obj";
5626 leency 20
 
8381 leency 21
dword libimg_init   = #alibimg_init;
22
dword img_is_img    = #aimg_is_img;
23
dword img_to_rgb2   = #aimg_to_rgb2;
24
dword img_decode    = #aimg_decode;
25
dword img_destroy   = #aimg_destroy;
26
dword img_draw      = #aimg_draw;
27
dword img_create    = #aimg_create;
28
dword img_encode    = #aimg_encode;
29
dword img_convert   = #aimg_convert;
30
dword img_from_file = #aimg_from_file;
7190 leency 31
 
3107 leency 32
//dword img_flip    = #aimg_flip;
33
//dword img_rotate  = #aimg_rotate;
3839 Asper 34
$DD 2 dup 0
3107 leency 35
 
36
//import  libimg                     , \
8381 leency 37
char alibimg_init[]   = "lib_init";
38
char aimg_is_img[]    = "img_is_img";
39
char aimg_to_rgb2[]   = "img_to_rgb2";
40
char aimg_decode[]    = "img_decode";
41
char aimg_destroy[]   = "img_destroy";
42
char aimg_draw[]      = "img_draw";
43
char aimg_create[]    = "img_create";
44
char aimg_encode[]    = "img_encode";
45
char aimg_convert[]   = "img_convert";
46
char aimg_from_file[] = "img_from_file";
7252 leency 47
//char aimg_flip[]    = "img_flip";
48
//char aimg_rotate[]  = "img_rotate ";
3107 leency 49
 
7977 leency 50
//invoke  img.scale, ebx, 0, 0, [ebx + Image.Width], [ebx + Image.Height], 0, LIBIMG_SCALE_TYPE_STRETCH, LIBIMG_SCALE_ALG_BILINEAR, edx, ecx
51
 
7190 leency 52
#define LIBIMG_FORMAT_BMP       1
53
#define LIBIMG_FORMAT_ICO       2
54
#define LIBIMG_FORMAT_CUR       3
55
#define LIBIMG_FORMAT_GIF       4
56
#define LIBIMG_FORMAT_PNG       5
57
#define LIBIMG_FORMAT_JPEG      6
58
#define LIBIMG_FORMAT_TGA       7
59
#define LIBIMG_FORMAT_PCX       8
60
#define LIBIMG_FORMAT_XCF       9
61
#define LIBIMG_FORMAT_TIFF     10
62
#define LIBIMG_FORMAT_PNM      11
63
#define LIBIMG_FORMAT_WBMP     12
64
#define LIBIMG_FORMAT_XBM      13
65
#define LIBIMG_FORMAT_Z80      14
3107 leency 66
 
7190 leency 67
// values for Image.Type
68
// must be consecutive to allow fast switch on Image.Type in support functions
7995 leency 69
#define IMAGE_BPP8i  1  // indexed
70
#define IMAGE_BPP24  2
71
#define IMAGE_BPP32  3
72
#define IMAGE_BPP15  4
73
#define IMAGE_BPP16  5
74
#define IMAGE_BPP1   6
75
#define IMAGE_BPP8g  7  // grayscale
76
#define IMAGE_BPP2i  8
77
#define IMAGE_BPP4i  9
78
#define IMAGE_BPP8a 10  // grayscale with alpha channel; application layer only!!!
7254 leency 79
                        // kernel doesn't handle this image type,
80
                        // libimg can only create and destroy such images
7190 leency 81
 
7995 leency 82
struct libimg_image
83
{
84
    dword checksum; // ((Width ROL 16) OR Height) XOR Data[0]        ; ignored so far
85
    dword w;
86
    dword h;
87
    dword next;
88
    dword previous;
89
    dword type;     // one of Image.bppN
90
    dword imgsrc;
91
    dword palette;  // used iff Type eq Image.bpp1, Image.bpp2, Image.bpp4 or Image.bpp8i
92
    dword extended;
93
    dword flags;    // bitfield
94
    dword delay;    // used iff Image.IsAnimated is set in Flags
95
    dword image;
96
    void load();
97
    void convert_into();
98
    void replace_color();
99
    void set_vars();
100
    void draw();
101
};
7190 leency 102
 
7995 leency 103
:void libimg_image::set_vars()
104
{
105
    $push edi
106
    EDI = image;
107
    checksum = DSWORD[EDI];
108
    w = ESDWORD[EDI+4];
109
    h = ESDWORD[EDI+8];
110
    next = ESDWORD[EDI+12];
111
    previous = ESDWORD[EDI+16];
112
    imgsrc = ESDWORD[EDI+24];
113
    palette = ESDWORD[EDI+28];
114
    extended = ESDWORD[EDI+32];
115
    flags = ESDWORD[EDI+36];
116
    delay = ESDWORD[EDI+40];
117
    $pop edi
118
}
119
 
120
:void libimg_image::load(dword file_path)
121
{
122
    load_image(file_path);
123
    if (!EAX) {
124
        notify("'Error: Image not loaded'E");
125
    } else {
126
        image = EAX;
127
        set_vars();
128
    }
129
}
130
 
131
:void libimg_image::replace_color(dword old_color, new_color)
132
{
133
    EDX =  w * h * 4 + imgsrc;
134
    for (ESI = imgsrc; ESI < EDX; ESI += 4) if (DSDWORD[ESI]==old_color) DSDWORD[ESI] = new_color;
135
}
136
 
137
:void libimg_image::draw(dword _x, _y, _w, _h, _xoff, _yoff)
138
{
139
    if (image) img_draw stdcall(image, _x, _y, _w, _h, _xoff, _yoff);
140
}
141
 
142
:void libimg_image::convert_into(dword _to)
143
{
144
    img_convert stdcall(image, 0, _to, 0, 0);
145
    if (!EAX) {
146
        notify("'LibImg convertation error!'E");
147
    } else {
148
        image = EAX;
149
        set_vars();
150
    }
151
}
152
 
7224 leency 153
:dword load_image(dword filename)
3107 leency 154
{
155
        //align 4
156
        dword img_data=0;
157
        dword img_data_len=0;
158
        dword fh=0;
159
        dword image=0;
160
 
161
        byte tmp_buf[40];
162
        $and     img_data, 0
163
        //$mov     eax, filename
164
        //$push    eax
165
        //invoke  file.open, eax, O_READ
166
        file_open stdcall (filename, O_READ);
167
        $or      eax, eax
168
        $jnz      loc05
169
        $stc
170
        return 0;
171
    @loc05:
172
        $mov     fh, eax
173
        //invoke  file.size
174
        file_size stdcall (filename);
175
        $mov     img_data_len, ebx
176
        //stdcall mem.Alloc, ebx
177
        mem_Alloc(EBX);
178
 
179
        $test    eax, eax
180
        $jz      error_close
181
        $mov     img_data, eax
182
        //invoke  file.read, [fh], eax, [img_data_len]
183
        file_read stdcall (fh, EAX, img_data_len);
184
        $cmp     eax, -1
185
        $jz      error_close
186
        $cmp     eax, img_data_len
187
        $jnz     error_close
188
        //invoke  file.close, [fh]
189
        file_close stdcall (fh);
190
        $inc     eax
191
        $jz      error_
192
//; img.decode checks for img.is_img
193
//;       //invoke  img.is_img, [img_data], [img_data_len]
194
//;       $or      eax, eax
195
//;       $jz      exit
196
        //invoke  img.decode, [img_data], [img_data_len], 0
197
        EAX=img_data;
198
        img_decode stdcall (EAX, img_data_len,0);
199
        $or      eax, eax
200
        $jz      error_
201
        $cmp     image, 0
202
        $pushf
203
        $mov     image, eax
204
        //call    init_frame
205
        $popf
206
        //call    update_image_sizes
207
        mem_Free(img_data);//free_img_data(img_data);
208
        $clc
209
        return image;
210
 
211
@error_free:
212
        //invoke  img.destroy, [image]
213
        img_destroy stdcall (image);
214
        $jmp     error_
215
 
216
@error_pop:
217
        $pop     eax
218
        $jmp     error_
219
@error_close:
220
        //invoke  file.close, [fh]
221
        file_close stdcall (fh);
222
@error_:
223
        mem_Free(img_data);
224
        $stc
225
        return 0;
226
}
5598 pavelyakov 227
 
7224 leency 228
:dword create_image(dword type, dword width, dword height) {
229
    img_create stdcall(width, height, type);
230
    return EAX;
231
}
232
 
233
// size - output parameter, error code / the size of encoded data
234
:dword encode_image(dword image_ptr, dword options, dword specific_options, dword* size) {
235
    img_encode stdcall(image_ptr, options, specific_options);
236
    ESDWORD[size] = ECX;
237
 
238
    return EAX;
239
}
240
 
7254 leency 241
//NOTICE: DO NOT FORGET TO INIT libio AND libimg!!!
7867 leency 242
#ifdef LANG_RUS
7893 leency 243
#define TEXT_FILE_SAVED_AS "'Файл сохранен как "
244
#else
7867 leency 245
#define TEXT_FILE_SAVED_AS "'File saved as "
246
#endif
7254 leency 247
:void save_image(dword _image_pointer, _w, _h, _path)
7224 leency 248
{
249
    char save_success_message[4096+200];
250
    dword encoded_data=0;
251
    dword encoded_size=0;
252
    dword image_ptr = 0;
253
 
7995 leency 254
    image_ptr = create_image(IMAGE_BPP24, _w, _h);
7190 leency 255
 
7224 leency 256
    if (image_ptr == 0) {
257
        notify("'Error saving file, probably not enought memory!' -E");
258
    }
259
    else {
260
        EDI = image_ptr;
7995 leency 261
        memmov(EDI.libimg_image.imgsrc, _image_pointer, _w * _h * 3);
7224 leency 262
 
263
        encoded_data = encode_image(image_ptr, LIBIMG_FORMAT_PNG, 0, #encoded_size);
264
 
265
        img_destroy stdcall(image_ptr);
266
 
267
        if(encoded_data == 0) {
268
            notify("'Error saving file, incorrect data!' -E");
269
        }
270
        else {
7227 leency 271
            if (CreateFile(encoded_size, encoded_data, _path) == 0) {
7867 leency 272
                strcpy(#save_success_message, TEXT_FILE_SAVED_AS);
7783 leency 273
                strcat(#save_success_message, _path);
274
                strcat(#save_success_message, "' -O");
7224 leency 275
                notify(#save_success_message);
276
            }
277
            else {
7783 leency 278
                notify("'Error saving image file!\nNot enough space? Path wrong?\nFile system is not writable?..' -E");
7224 leency 279
            }
280
        }
281
    }
7190 leency 282
}
283
 
7995 leency 284
 
285
 
286
/////////////////////////////
287
/*
288
//  DRAW ICON PATTERN / TEMP
289
*/
290
/////////////////////////////
291
 
292
:void DrawIcon32(dword x,y, _bg, icon_n) {
293
    static dword bg;
8381 leency 294
    static dword pure_img32;
295
    if (!pure_img32) || (bg!=_bg) {
7995 leency 296
        bg = _bg;
8381 leency 297
        img_from_file stdcall("/sys/icons32.png");
298
        pure_img32 = EAX;
299
        //now fill transparent with another color
300
        EDX = ESDWORD[EAX+4] * ESDWORD[EAX+8] * 4 + ESDWORD[EAX+24];
301
        for (ESI = ESDWORD[EAX+24]; ESI < EDX; ESI += 4) {
302
            if (DSDWORD[ESI]==0x00000000) DSDWORD[ESI] = bg;
303
        }
7995 leency 304
    }
8381 leency 305
    img_draw stdcall(pure_img32, x, y, 32, 32, 0, icon_n*32);
7977 leency 306
}
307
 
8381 leency 308
:void DrawIcon16(dword x,y, _bg, icon_n) {
309
    static dword bg;
310
    static dword pure_img16;
311
    dword bgshadow;
312
    if (!pure_img16) || (bg!=_bg) {
313
        bg = _bg;
314
        bgshadow = MixColors(bg, 0, 220);
315
        img_from_file stdcall("/sys/icons16.png");
316
        pure_img16 = EAX;
317
        //now fill transparent with another color
318
        EDX = ESDWORD[EAX+4] * ESDWORD[EAX+8] * 4 + ESDWORD[EAX+24];
319
        for (ESI = ESDWORD[EAX+24]; ESI < EDX; ESI += 4) {
320
            if (DSDWORD[ESI]==0xffFFFfff) DSDWORD[ESI] = bg;
321
            if (DSDWORD[ESI]==0xffCACBD6) DSDWORD[ESI] = bgshadow;
322
        }
7995 leency 323
    }
8381 leency 324
    img_draw stdcall(pure_img16, x, y, 16, 16, 0, icon_n*16);
7995 leency 325
}
7224 leency 326
 
5598 pavelyakov 327
#endif