Subversion Repositories Kolibri OS

Rev

Rev 958 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
958 leency 1
#include "kosSyst.h"
2
#include "gfx.cpp"
3
#include "dlgopen.h"
4
#include "formats\pcx.h"
5
#include "formats\bmp.h"
6
#include "formats\tga.h"
7
 
8
#define  btn_open    10
9
#define  btn_prev    11
10
#define  btn_next    12
11
#define  btn_fit     13
12
 
13
#define  scrl_up     30
14
#define  scrl_down   31
15
#define  scrl_left   32
16
#define  scrl_right  33
17
 
18
char  params[2048] = "PARAM";
19
const char header[] = "ImageView v 0.08";
20
int   image_opened=0;
21
 
22
Byte* image_buffer=NULL;  // Полное RAW-Изображение
23
Byte* img_cuted=NULL;     // Усеченное RAW-изображение (используется при прокрутке или масштабировании)
24
Byte* cur_files=NULL;     // Буфер для общего списка файлов текущей папки
25
Word* img_files=NULL;     // Указатель массив со список граф.файлов в текущей папке
26
Dword cnt_imgfiles;       // Количество элементов массива img_files[]
27
Dword cur_image;          // Номер текущего изображения в массиве
28
char  cur_folder[512];    // Путь к текущей папке с / на конце
29
 
30
Dword image_width;
31
Dword image_height;
32
Dword old_status_size=0;
33
 
34
char szStatus[256];
35
bool scale=0;
36
 
37
 
38
sProcessInfo proc;
39
Dword img_area_left,img_area_top,img_area_width,img_area_height;
40
int vscrl_max=100,vscrl_value=0,vscrl_coord_x,vscrl_coord_y,vscrl_coord_min,vscrl_coord_max,vscrl_using=0;
41
int hscrl_max=100,hscrl_value=0,hscrl_coord_x,hscrl_coord_y,hscrl_coord_min,hscrl_coord_max,hscrl_using=0;
42
Dword width_old,height_old;
43
 
44
/* Вырезает квадрат из изображения по координатам*/
45
void GetRectImage(Byte* src, Byte* dst, Dword left,Dword top,Dword width,Dword height)
46
{
47
  int x,y;
48
  int pImgS,pImgD=0;
49
 
50
  for(y=top;y
51
  {
52
    for(x=left;x
53
    {
54
      pImgS=y*image_width*3+x*3;
55
      *(dst+pImgD+0)=*(src+pImgS+0);
56
      *(dst+pImgD+1)=*(src+pImgS+1);
57
      *(dst+pImgD+2)=*(src+pImgS+2);
58
      pImgD=pImgD+3;
59
    }
60
  }
61
}
62
 
63
/* Растягивает изображение в меньшую сторону (иначе нужно выделять больше памяти под img_cuted) */
64
void ResizeImage(Byte* src, Byte* dst, Dword new_width,Dword new_height)
65
{
66
  int x,y,src_y,src_x;
67
  int pImgS,pImgD=0;
68
  for(y=0;y
69
  {
70
    for(x=0;x
71
    {
72
      __asm
73
      {
74
        finit
75
        fild   image_width
76
        fidiv  new_width
77
        fild   x
78
        fmul   st(0),st(1)
79
        fistp  src_x
80
        fild   image_height
81
        fidiv  new_height
82
        fild   y
83
        fmul   st(0),st(1)
84
        fistp  src_y
85
      }
86
      pImgS=src_y*image_width*3+src_x*3;
87
      pImgD=y*new_width*3+x*3;
88
      *(dst+pImgD+0)=*(src+pImgS+0);
89
      *(dst+pImgD+1)=*(src+pImgS+1);
90
      *(dst+pImgD+2)=*(src+pImgS+2);
91
    }
92
  }
93
}
94
 
95
void set_vscroll_values(Dword max, Dword value)
96
{
97
  vscrl_max=max;
98
  vscrl_value=value;
99
  kos_DrawBar(vscrl_coord_x,vscrl_coord_y,15,35,0xDADADA);
100
  vscrl_coord_y=vscrl_coord_min+((value*(vscrl_coord_max-vscrl_coord_min-35))/vscrl_max);
101
  kos_PutImage(scroll_v,15,35,vscrl_coord_x,vscrl_coord_y);
102
}
103
 
104
void set_hscroll_values(Dword max, Dword value)
105
{
106
  hscrl_max=max;
107
  hscrl_value=value;
108
  kos_DrawBar(hscrl_coord_x,hscrl_coord_y,35,15,0xDADADA);
109
  hscrl_coord_x=hscrl_coord_min+((value*(hscrl_coord_max-hscrl_coord_min-35))/hscrl_max);
110
  kos_PutImage(scroll_h,35,15,hscrl_coord_x,hscrl_coord_y);
111
}
112
 
113
void draw_image()
114
{
115
  Dword new_width,new_height,scale_left,scale_top;
116
  if (!image_opened) return;
117
 
118
  if (scale==0)
119
  {
120
    /* Здесь вывод изображения с использованием полос прокрутки */
121
    new_width = image_width <= img_area_width ? image_width : img_area_width;
122
    new_height = image_height <= img_area_height ? image_height : img_area_height;
123
    GetRectImage(image_buffer, img_cuted, hscrl_value, vscrl_value, new_width, new_height);
124
    kos_PutImage((RGB*)img_cuted, new_width, new_height, img_area_left,img_area_top);
125
  } else {
126
    /* Здесь вывод изображения с использованием масштабирования, сохраняя пропорции */
127
    __asm
128
    {
129
      finit
130
      fild   img_area_width
131
      fidiv  image_width
132
      fild   image_width
133
      fmul   st(0),st(1)
134
      fistp  new_width
135
      fild   image_height
136
      fmul   st(0),st(1)
137
      fistp  new_height
138
    }
139
    if (img_area_height
140
    {
141
      __asm
142
      {
143
        finit
144
        fild   img_area_height
145
        fidiv  image_height
146
        fild   image_width
147
        fmul   st(0),st(1)
148
        fistp  new_width
149
        fild   image_height
150
        fmul   st(0),st(1)
151
        fistp  new_height
152
      }
153
    }
154
 
155
    /* это в случае не пропорционального масштабирования */
156
    //new_width=img_area_width;
157
    //new_height=img_area_height;
158
 
159
    if (new_width>image_width) new_width=image_width;
160
    if (new_height>image_height) new_height=image_height;
161
 
162
    ResizeImage(image_buffer,img_cuted,new_width,new_height);
163
    /* Центрирование изображения */
164
    scale_left=(img_area_width/2)-(new_width/2);
165
    scale_top=(img_area_height/2)-(new_height/2);
166
    kos_PutImage((RGB*)img_cuted,new_width,new_height,img_area_left+scale_left,img_area_top+scale_top);
167
  }
168
}
169
 
170
void draw_window(void)
171
{
172
  kos_WindowRedrawStatus(1);
173
  kos_DefineAndDrawWindow(0,0,450,350,0x33,0xEFEBEF,0,0,(Dword)header);
174
 
175
  //ToolBar
176
    //open
177
    kos_DefineButton(2,4,20,20,btn_open+0x40000000,0xEFEBEF);
178
    kos_PutImage(tbOpen,21,21,2,4);
179
    //prev
180
    kos_DefineButton(25,4,20,20,btn_prev+0x40000000,0xEFEBEF);
181
    kos_PutImage(tbPrev,21,21,25,4);
182
    //next
183
    kos_DefineButton(48,4,20,20,btn_next+0x40000000,0xEFEBEF);
184
    kos_PutImage(tbNext,21,21,48,4);
185
    //fit image
186
    kos_DefineButton(71,4,20,20,btn_fit+0x40000000,0xEFEBEF);
187
    kos_PutImage(tbFit,21,21,71,4);
188
 
189
  //Lines
190
    kos_ProcessInfo(&proc,-1);
191
    kos_DrawBar(2,30,proc.processInfo.work_width-3,1,0x94AECE);
192
 
193
  //Scroll controls
194
    //vertical scroll bar
195
    vscrl_coord_x=proc.processInfo.work_width-16;
196
    vscrl_coord_max=proc.processInfo.work_height-46;
197
    kos_DrawBar(proc.processInfo.work_width-16,33,15,proc.processInfo.work_height-79,0xDADADA);
198
    kos_DefineButton(proc.processInfo.work_width-16,33,14,14,scrl_up+0x40000000,0xEFEBEF);
199
    kos_DefineButton(proc.processInfo.work_width-16,proc.processInfo.work_height-46,14,14,scrl_down+0x40000000,0xEFEBEF);
200
    kos_PutImage(arrow_up,15,15,proc.processInfo.work_width-16,33);
201
    kos_PutImage(arrow_down,15,15,proc.processInfo.work_width-16,proc.processInfo.work_height-46);
202
    kos_PutImage(scroll_v,15,35,vscrl_coord_x,vscrl_coord_y);
203
 
204
 
205
    //horisontal scroll bar
206
    hscrl_coord_y=proc.processInfo.work_height-31;
207
    hscrl_coord_max=proc.processInfo.work_width-31;
208
    kos_DrawBar(2,proc.processInfo.work_height-31,proc.processInfo.work_width-18,15,0xDADADA);
209
    kos_DefineButton(2,proc.processInfo.work_height-31,14,14,scrl_left+0x40000000,0xEFEBEF);
210
    kos_DefineButton(proc.processInfo.work_width-31,proc.processInfo.work_height-31,14,14,scrl_right+0x40000000,0xEFEBEF);
211
    kos_PutImage(arrow_left,15,15,2,proc.processInfo.work_height-31);
212
    kos_PutImage(arrow_right,15,15,proc.processInfo.work_width-31,proc.processInfo.work_height-31);
213
    kos_PutImage(scroll_h,35,15,hscrl_coord_x,hscrl_coord_y);
214
 
215
  img_area_left=2;
216
  img_area_top=33;
217
  img_area_width=proc.processInfo.work_width-img_area_left-3-16;
218
  img_area_height=proc.processInfo.work_height-img_area_top-3-16-15;
219
 
220
  kos_WriteTextToWindow(2,proc.processInfo.work_height-12, 0x80, 0, szStatus, 0);
221
 
222
  if (img_area_width
223
  if (img_area_height
224
 
225
  draw_image();
226
 
227
  kos_WindowRedrawStatus(2);
228
}
229
 
230
void LoadPCX(Byte* filebuff, Dword filesize)
231
{
232
  PCXFile pcx;
233
  if (!pcx.LoadPCXFile(filebuff,filesize))
234
  {
235
    image_opened=1;
236
    image_buffer=pcx.buffer;
237
    image_width=pcx.width;
238
    image_height=pcx.height;
239
  } else {
240
    image_opened=0;
241
  }
242
}
243
 
244
void LoadBMP(Byte* filebuff, Dword filesize)
245
{
246
  BMPFile bmp;
247
  if (!bmp.LoadBMPFile(filebuff,filesize))
248
  {
249
    image_opened=1;
250
    image_buffer=bmp.buffer;
251
    image_width=bmp.width;
252
    image_height=bmp.height;
253
  } else {
254
    image_opened=0;
255
  }
256
}
257
 
258
void LoadTGA(Byte* filebuff, Dword filesize)
259
{
260
  TGAFile tga;
261
  if (!tga.LoadTGAFile(filebuff,filesize))
262
  {
263
    image_opened=1;
264
    image_buffer=tga.buffer;
265
    image_width=tga.width;
266
    image_height=tga.height;
267
  } else {
268
    image_opened=0;
269
  }
270
}
271
 
272
//Загрузить список файлов, поддерживаемых программой из папки с текущим файлом
273
void load_folder(char* imgfile)
274
{
275
  kosFileInfo fi;
276
  char* cPtr;
277
  int i;
278
 
279
  // Извлечем имя папки
280
  strcpy(fi.fileURL, imgfile);
281
  cPtr=strrchr(fi.fileURL,'/');
282
  cPtr[1]=0;
283
  strcpy(cur_folder,fi.fileURL);
284
 
285
  if (cur_files) { kos_FreeMemory(cur_files); cur_files=NULL;}
286
  if (img_files) { kos_FreeMemory((Byte*)img_files); img_files=NULL;}
287
 
288
  /* Выделим память под файл */
289
  cur_files = kos_GetMemory(65536);
290
  fi.rwMode = 1;
291
  fi.OffsetLow = 0;
292
  fi.OffsetHigh = 0;
293
  fi.dataCount = 65536;
294
  fi.bufferPtr = cur_files;
295
  int state = kos_FileSystemAccess(&fi);
296
  if (state!=0 && state!=6) {kos_FreeMemory(cur_files); cur_files=NULL; return;}
297
 
298
  Dword file_count=*(cur_files+8);
299
  img_files = (Word*)kos_GetMemory(4*file_count);
300
 
301
  char* image_name;
302
  cnt_imgfiles=0;
303
  cur_image=-1;
304
 
305
  lcase(imgfile);
306
  for(i=0;i
307
  {
308
    image_name=(char*)cur_files+32+i*304+40;
309
    lcase(image_name);
310
    cPtr=strrchr(image_name,'.');
311
    if (strcmp((char*)cPtr,".bmp") || strcmp((char*)cPtr,".pcx") || strcmp((char*)cPtr,".tga"))
312
    {
313
      cPtr=strrchr(imgfile,'/');
314
      if (strcmp(cPtr+1,image_name)) cur_image=cnt_imgfiles;
315
      ((Word*)img_files)[cnt_imgfiles]=i;
316
      cnt_imgfiles++;
317
    }
318
  }
319
  cnt_imgfiles--;
320
}
321
 
322
void open_imgfile(char* imgfile)
323
{
324
  Word scr_left,scr_top,scr_right,scr_bot;
325
  Word win_width,win_height;
326
  Dword skin_height;
327
  kosFileInfo fi;
328
  Dword file_size;
329
  Byte* filebuff;
330
  Byte* infoBuf;
331
 
332
 
333
  /* Вычислим размер файла */
334
  infoBuf = kos_GetMemory(40); /* Буфер для инфо-структуры */
335
  fi.rwMode = 5;
336
  fi.OffsetLow = 0;
337
  fi.OffsetHigh = 0;
338
  fi.dataCount = 0;
339
  fi.bufferPtr = infoBuf;
340
  strcpy(fi.fileURL, imgfile);
341
  if (kos_FileSystemAccess(&fi)) { kos_FreeMemory(infoBuf); return;}
342
  file_size=*(Dword*)(infoBuf+32);
343
  kos_FreeMemory(infoBuf);
344
 
345
  /* Выделим память под файл */
346
  filebuff = kos_GetMemory(file_size);
347
  fi.rwMode = 0;
348
  fi.OffsetLow = 0;
349
  fi.OffsetHigh = 0;
350
  fi.dataCount = file_size;
351
  fi.bufferPtr = filebuff;
352
  strcpy(fi.fileURL, imgfile);
353
  if (kos_FileSystemAccess(&fi)) { kos_FreeMemory(filebuff); return;}
354
 
355
  /* Определяем тип файла */
356
  //lcase(imgfile); уже в нижнем регистре: это выполняется в load_folder
357
  char* cPtr;
358
  cPtr=strrchr(imgfile,'.');
359
  if (strcmp((char*)cPtr,".bmp")) LoadBMP(filebuff,file_size);
360
  if (strcmp((char*)cPtr,".pcx")) LoadPCX(filebuff,file_size);
361
  if (strcmp((char*)cPtr,".tga")) LoadTGA(filebuff,file_size);
362
  cPtr=strrchr(imgfile,'/')+1;
363
  if (image_opened)
364
  {
365
    sprintf(szStatus,"” ©« %S... [%U/%U]",cPtr,cur_image+1,cnt_imgfiles+1);
366
 
367
    __asm
368
    {
369
      mov  eax,48
370
      mov  ebx,5
371
      int  40h
372
      mov  scr_right,ax
373
      shr  eax,16
374
      mov  scr_bot,bx
375
      shr  ebx,16
376
      mov  scr_left,ax
377
      mov  scr_top,bx
378
      mov  eax,48
379
      mov  ebx,4
380
      int  40h
381
      mov  skin_height,eax
382
    }
383
 
384
    if (scr_right-scr_left+1>image_width) win_width=image_width+img_area_left+3+16+10; else win_width=scr_right-scr_left+1;
385
    if (scr_bot-scr_top+1>image_height) win_height=image_height+img_area_top+3+16+15+5+skin_height; else win_height=scr_bot-scr_top+1;
386
 
387
    if (win_width<150) win_width=150;
388
    if (win_height<160) win_height=160;
389
 
390
    img_cuted=kos_GetMemory(image_width*image_height*3);
391
    kos_ChangeWindow(scr_left,scr_top,win_width,win_height);
392
 
393
    if (img_area_width
394
    if (img_area_height
395
  } else {
396
    sprintf(szStatus,"” ©« %S ­Ґ § Ја㦥­. ”®а¬ в ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп.",cPtr);
397
  }
398
  draw_window();
399
  kos_FreeMemory(filebuff);
400
}
401
 
402
void show_dlg()
403
{
404
  char* imgfile;
405
  imgfile=DialogOpenFile(&draw_window);
406
  if (!imgfile) return;
407
  load_folder(imgfile);
408
  //Если файл уже был открыт...
409
  if (image_opened)
410
  {
411
    image_opened=0;
412
    kos_FreeMemory(image_buffer); image_buffer=NULL;
413
    kos_FreeMemory(img_cuted); img_cuted=NULL;
414
  }
415
  open_imgfile(imgfile);
416
}
417
 
418
void kos_Main()
419
{
420
  Dword btnID;
421
  Byte keyCode;
422
  Dword mButton;
423
  int  mX,mXOld;
424
  int  mY,mYOld;
425
  char label1[100];
426
 
427
  /* Инициализация кучи процесса */
428
  __asm
429
  {
430
    mov  eax,68
431
    mov  ebx,11
432
    int  40h
433
  }
434
 
435
  vscrl_coord_min=vscrl_coord_y=33+15;
436
  hscrl_coord_min=hscrl_coord_x=2+15;
437
  strcpy(szStatus,"” ©« ­Ґ § Ја㦥­");
438
 
439
  draw_window();
440
  if (params[0]!='P') {load_folder(params); open_imgfile(params);}
441
  kos_SetMaskForEvents(0x27);
442
  for (;;)
443
  {
444
    switch (kos_WaitForEvent(10))
445
    {
446
       case 1:
447
         draw_window();
448
       break;
449
 
450
       case 2:
451
         kos_GetKey(keyCode);
452
       break;
453
 
454
       case 3:
455
         kos_GetButtonID(btnID);
456
         switch (btnID)
457
         {
458
           case 1:
459
             //Освободим память
460
             if (image_buffer) kos_FreeMemory(image_buffer);
461
             if (img_cuted) kos_FreeMemory(img_cuted);
462
             if (cur_files) kos_FreeMemory(cur_files);
463
             if (img_files) kos_FreeMemory((Byte*)img_files);
464
             kos_ExitApp();
465
           break;
466
 
467
           case btn_open:
468
             show_dlg();
469
           break;
470
 
471
           //Используем уже не нужный нам params
472
           case btn_prev:
473
             if (!cur_files) break;
474
             if (!cur_image) cur_image=cnt_imgfiles; else cur_image--;
475
             strcpy(params,cur_folder);
476
             strcpy(params+strlen(cur_folder),(char*)cur_files+32+((Word*)img_files)[cur_image]*304+40);
477
             open_imgfile(params);
478
           break;
479
 
480
           case btn_next:
481
             if (!cur_files) break;
482
             if (cur_image==cnt_imgfiles) cur_image=0; else cur_image++;
483
             strcpy(params,cur_folder);
484
             strcpy(params+strlen(cur_folder),(char*)cur_files+32+((Word*)img_files)[cur_image]*304+40);
485
             open_imgfile(params);
486
           break;
487
 
488
/*
489
           case scrl_up:
490
             if (vscrl_max==1 || vscrl_coord_y<=vscrl_coord_min) break;
491
             set_vscroll_values(vscrl_max, ((vscrl_coord_y - 2 - vscrl_coord_min) * vscrl_max) / (vscrl_coord_max - vscrl_coord_min - 35));
492
           break;
493
 
494
           case scrl_down:
495
             if (vscrl_max == 1 || vscrl_coord_y >= vscrl_coord_max) break;
496
             set_vscroll_values(vscrl_max, ((vscrl_coord_y + 2 - vscrl_coord_min) * vscrl_max) / (vscrl_coord_max - vscrl_coord_min - 35));
497
           break;
498
*/
499
 
500
           case btn_fit:
501
             scale = scale ? 0 : 1;
502
             draw_window();
503
           break;
504
 
505
         }
506
       break;
507
 
508
       case 6:
509
       default:
510
           kos_GetMouseState(mButton,mX,mY);
511
           //Вертикальная прокрутка
512
           if (mButton==1)
513
           {
514
             if (vscrl_using)
515
             {
516
               kos_DrawBar(vscrl_coord_x,vscrl_coord_y,15,35,0xDADADA);
517
               if (vscrl_coord_y+mY-mYOld
518
               {
519
                 vscrl_value=0;
520
                 vscrl_coord_y=vscrl_coord_min;
521
               } else if (vscrl_coord_y+35+mY-mYOld>vscrl_coord_max) {
522
                 vscrl_value=vscrl_max;
523
                 vscrl_coord_y=vscrl_coord_max-35;
524
               } else {
525
                 vscrl_value=(((vscrl_coord_y-vscrl_coord_min)*vscrl_max)/(vscrl_coord_max-vscrl_coord_min-35));
526
                 vscrl_coord_y=vscrl_coord_y+mY-mYOld;
527
                 mYOld=mY;
528
               }
529
               kos_PutImage(scroll_v,15,35,vscrl_coord_x,vscrl_coord_y);
530
               draw_image();
531
             } else {
532
               if (mY>=vscrl_coord_y && mY<=vscrl_coord_y+35 && mX>=vscrl_coord_x && mX<=vscrl_coord_x+15)
533
               {
534
                 vscrl_using=1;
535
                 mYOld=mY;
536
               }
537
             }
538
           } else if(mButton==0) {
539
             if (vscrl_using) {vscrl_using=0; draw_image();}
540
           }
541
           //Горизонтальная прокрутка
542
           if (mButton==1)
543
           {
544
             if (hscrl_using)
545
             {
546
               kos_DrawBar(hscrl_coord_x,hscrl_coord_y,35,15,0xDADADA);
547
               if (hscrl_coord_x+mX-mXOld
548
               {
549
                 hscrl_value=0;
550
                 hscrl_coord_x=hscrl_coord_min;
551
               } else if (hscrl_coord_x+35+mX-mXOld>hscrl_coord_max) {
552
                 hscrl_value=hscrl_max;
553
                 hscrl_coord_x=hscrl_coord_max-35;
554
               } else {
555
                 hscrl_value=(((hscrl_coord_x-hscrl_coord_min)*hscrl_max)/(hscrl_coord_max-hscrl_coord_min-35));
556
                 hscrl_coord_x=hscrl_coord_x+mX-mXOld;
557
                 mXOld=mX;
558
               }
559
               kos_PutImage(scroll_h,35,15,hscrl_coord_x,hscrl_coord_y);
560
               draw_image();
561
             } else {
562
               if (mX>=hscrl_coord_x && mX<=hscrl_coord_x+35 && mY>=hscrl_coord_y && mY<=hscrl_coord_y+15)
563
               {
564
                 hscrl_using=1;
565
                 mXOld=mX;
566
               }
567
             }
568
           } else if(mButton==0) {
569
             if (hscrl_using) {hscrl_using=0; draw_image();}
570
           }
571
 
572
       break;
573
    }
574
  }
575
}