From aef7c5284b08d119610c7e39ad6186a3457111b7 Mon Sep 17 00:00:00 2001 From: "Kirill Lipatov (Leency)" Date: Sat, 13 Dec 2008 23:11:59 +0000 Subject: [PATCH] imgview 0.08 git-svn-id: svn://kolibrios.org@958 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/media/imgview/MCSMEMM.H | 28 + programs/media/imgview/STDARG.H | 163 +++++ programs/media/imgview/bin/ChangeLog | 29 + programs/media/imgview/bin/readme | 26 + programs/media/imgview/compile.bat | 6 + programs/media/imgview/dlgopen.cpp | 107 +++ programs/media/imgview/dlgopen.h | 1 + programs/media/imgview/formats/bmp.cpp | 122 ++++ programs/media/imgview/formats/bmp.h | 45 ++ programs/media/imgview/formats/pcx.cpp | 55 ++ programs/media/imgview/formats/pcx.h | 31 + programs/media/imgview/formats/tga.cpp | 103 +++ programs/media/imgview/formats/tga.h | 37 + programs/media/imgview/gfx.cpp | 215 ++++++ programs/media/imgview/img/btn_fit.bmp | Bin 0 -> 1398 bytes programs/media/imgview/img/btn_next.bmp | Bin 0 -> 1398 bytes programs/media/imgview/img/btn_open.bmp | Bin 0 -> 1398 bytes programs/media/imgview/img/btn_prev.bmp | Bin 0 -> 1398 bytes programs/media/imgview/img/template.bmp | Bin 0 -> 1398 bytes programs/media/imgview/kosSyst.cpp | 921 ++++++++++++++++++++++++ programs/media/imgview/kosSyst.h | 203 ++++++ programs/media/imgview/main.cpp | 575 +++++++++++++++ programs/media/imgview/mcsmemm.cpp | 329 +++++++++ 23 files changed, 2996 insertions(+) create mode 100644 programs/media/imgview/MCSMEMM.H create mode 100644 programs/media/imgview/STDARG.H create mode 100644 programs/media/imgview/bin/ChangeLog create mode 100644 programs/media/imgview/bin/readme create mode 100644 programs/media/imgview/compile.bat create mode 100644 programs/media/imgview/dlgopen.cpp create mode 100644 programs/media/imgview/dlgopen.h create mode 100644 programs/media/imgview/formats/bmp.cpp create mode 100644 programs/media/imgview/formats/bmp.h create mode 100644 programs/media/imgview/formats/pcx.cpp create mode 100644 programs/media/imgview/formats/pcx.h create mode 100644 programs/media/imgview/formats/tga.cpp create mode 100644 programs/media/imgview/formats/tga.h create mode 100644 programs/media/imgview/gfx.cpp create mode 100644 programs/media/imgview/img/btn_fit.bmp create mode 100644 programs/media/imgview/img/btn_next.bmp create mode 100644 programs/media/imgview/img/btn_open.bmp create mode 100644 programs/media/imgview/img/btn_prev.bmp create mode 100644 programs/media/imgview/img/template.bmp create mode 100644 programs/media/imgview/kosSyst.cpp create mode 100644 programs/media/imgview/kosSyst.h create mode 100644 programs/media/imgview/main.cpp create mode 100644 programs/media/imgview/mcsmemm.cpp diff --git a/programs/media/imgview/MCSMEMM.H b/programs/media/imgview/MCSMEMM.H new file mode 100644 index 0000000000..42d61eaadb --- /dev/null +++ b/programs/media/imgview/MCSMEMM.H @@ -0,0 +1,28 @@ +// + +struct MemBlock +{ + Dword Size; + Dword Addr; + MemBlock *Next; + MemBlock *Previous; +}; + + +#define INITIALQUEUESIZE (32 * 4) + +#define FALSE 0 +#define TRUE -1 + +#define MB_FREE 0 +#define MB_USER 1 + +#define SIZE_ALIGN 4 + + + +Byte *allocmem( Dword reqsize ); +Dword freemem( void *vaddress ); + + + diff --git a/programs/media/imgview/STDARG.H b/programs/media/imgview/STDARG.H new file mode 100644 index 0000000000..9ffd22538c --- /dev/null +++ b/programs/media/imgview/STDARG.H @@ -0,0 +1,163 @@ +/*** +*stdarg.h - defines ANSI-style macros for variable argument functions +* +* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This file defines ANSI-style macros for accessing arguments +* of functions which take a variable number of arguments. +* [ANSI] +* +* [Public] +* +****/ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#ifndef _INC_STDARG +#define _INC_STDARG + +#if !defined(_WIN32) && !defined(_MAC) +#error ERROR: Only Mac or Win32 targets supported! +#endif + + +#ifdef _MSC_VER +/* + * Currently, all MS C compilers for Win32 platforms default to 8 byte + * alignment. + */ +#pragma pack(push,8) +#endif /* _MSC_VER */ + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifndef _VA_LIST_DEFINED +#ifdef _M_ALPHA +typedef struct { + char *a0; /* pointer to first homed integer argument */ + int offset; /* byte offset of next parameter */ +} va_list; +#else +typedef char * va_list; +#endif +#define _VA_LIST_DEFINED +#endif + +#ifdef _M_IX86 + + +#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) + +#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) +#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) +#define va_end(ap) ( ap = (va_list)0 ) + +#elif defined(_M_MRX000) + + +/* Use these types and definitions if generating code for MIPS */ + +#define va_start(ap,v) ap = (va_list)&v + sizeof(v) +#define va_end(list) +#define va_arg(list, mode) ((mode *)(list =\ + (char *) ((((int)list + (__builtin_alignof(mode)<=4?3:7)) &\ + (__builtin_alignof(mode)<=4?-4:-8))+sizeof(mode))))[-1] + +/* +++++++++++++++++++++++++++++++++++++++++++ + Because of parameter passing conventions in C: + use mode=int for char, and short types + use mode=double for float types + use a pointer for array types + +++++++++++++++++++++++++++++++++++++++++++ */ + + +#elif defined(_M_ALPHA) + + +/* Use these types and definitions if generating code for ALPHA */ + +/* + * The Alpha compiler supports two builtin functions that are used to + * implement stdarg/varargs. The __builtin_va_start function is used + * by va_start to initialize the data structure that locates the next + * argument. The __builtin_isfloat function is used by va_arg to pick + * which part of the home area a given register argument is stored in. + * The home area is where up to six integer and/or six floating point + * register arguments are stored down (so they can also be referenced + * by a pointer like any arguments passed on the stack). + */ + +extern void * __builtin_va_start(va_list, ...); + +#ifdef _CFRONT +#define __builtin_isfloat(a) __builtin_alignof(a) +#endif + +#define va_start(list, v) __builtin_va_start(list, v, 1) +#define va_end(list) +#define va_arg(list, mode) \ + ( *( ((list).offset += ((int)sizeof(mode) + 7) & -8) , \ + (mode *)((list).a0 + (list).offset - \ + ((__builtin_isfloat(mode) && (list).offset <= (6 * 8)) ? \ + (6 * 8) + 8 : ((int)sizeof(mode) + 7) & -8) \ + ) \ + ) \ + ) + +#elif defined(_M_PPC) + +/* Microsoft C8 front end (used in Motorola Merged compiler) */ +/* bytes that a type occupies in the argument list */ +#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) +/* return 'ap' adjusted for type 't' in arglist */ +#define _ALIGNIT(ap,t) \ + ((((int)(ap))+(sizeof(t)<8?3:7)) & (sizeof(t)<8?~3:~7)) + +#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) +#define va_arg(ap,t) ( *(t *)((ap = (char *) (_ALIGNIT(ap, t) + _INTSIZEOF(t))) - _INTSIZEOF(t)) ) +#define va_end(ap) ( ap = (va_list)0 ) + +#elif defined(_M_M68K) +#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) + +#define va_start(ap,v) ( ap = (va_list)&v + (sizeof(v) < sizeof(int) ? sizeof(v) : _INTSIZEOF(v)) ) +#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) +#define va_end(ap) ( ap = (va_list)0 ) + +#elif defined(_M_MPPC) +#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) + +#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) +#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) +#define va_end(ap) ( ap = (va_list)0 ) + +#else + +/* A guess at the proper definitions for other platforms */ + +#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) + +#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) +#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) +#define va_end(ap) ( ap = (va_list)0 ) + + +#endif + + +#ifdef __cplusplus +} +#endif + +#ifdef _MSC_VER +#pragma pack(pop) +#endif /* _MSC_VER */ + +#endif /* _INC_STDARG */ diff --git a/programs/media/imgview/bin/ChangeLog b/programs/media/imgview/bin/ChangeLog new file mode 100644 index 0000000000..dc0c0b0ba2 --- /dev/null +++ b/programs/media/imgview/bin/ChangeLog @@ -0,0 +1,29 @@ +Версия 0.08 - + = Устарнена ошибка: программа вылетала при открытии несуществующего файла + = Устарнена ошибка: при открытии файла через параметры, окно не подстраивалось под размеры изображения + +Версия 0.07 - 05.08.08: + = Исправлена ошибка с постоянной перерисовкой изображения + = При открытии большого изображения окно не выезжает за пределы экрана (касается эмулятора) + = Оптимизация кода + = Новые иконки для кнопок (25х25 -> 21х21) + = Новый режим отображения: подгонять под размеры окна (с сохранением пропорций изображения) + = Подогнанное изображение центрируется + +Версия 0.05 - 14.07.08: + = Устранен баг с исчезновением полос прокрутки, и вообще скроллы стали юзабельней + = Правильно отображаются перевернутые tga + = Добавлены черно-белые и 16-ти цветные bmp + = Исправление мелких, не влияющих на основную работу, ошибок + +Версия 0.04 - 09.07.08: + = Уменьшен размер программы, за счет удаления одинакового кода. + = Изображение не выгружается до тех пор, пока не будет открыто новое. + = Добавлен 16-битный bmp. + = Исправлена ошибка с утечкой памяти. + = Теперь с помощью соответствующих кнопок можно просматривать все, поддерживаемые программой, + файлы текущего каталога, не выходя из программы. + = Добавлена строка статуса + +Версия 0.01 - 04.07.08: + = Первая версия программы. \ No newline at end of file diff --git a/programs/media/imgview/bin/readme b/programs/media/imgview/bin/readme new file mode 100644 index 0000000000..a1e84415dc --- /dev/null +++ b/programs/media/imgview/bin/readme @@ -0,0 +1,26 @@ +ImageView v 0.07 +-------------------------------------------------------------- + +Описание +======== +Эта программа предназначена для удобного просмотра графических +файлов. Поддерживаемые форматы: bmp (без сжатия), pcx (только +256-цветные), tga (не все). Поддерживает запуск с параметрами, +поэтому можно сделать в KFAR ассоциации с соответствующими +файлами. + + +Интерфейс +========= +Программа имеет интуитивно понятный интерфейс. В верхней части +окна расположена панель управляющих кнопок. Вот их назначение +(слева направо): открыть файл, перейти к предыдущиму файлу в +каталоге, перейти к следующему файлу в каталоге, переключить +режим просмотра. Внизу окна имеется строка состояния, отобра- +жающая имя текущего файла, его номер в каталоге и общее число +поддерживаемых файлов в каталоге. + + + Sh@dy 05.08.08 + alex_megasoft@mail.ru + http://artech.org.ru/ \ No newline at end of file diff --git a/programs/media/imgview/compile.bat b/programs/media/imgview/compile.bat new file mode 100644 index 0000000000..75a6803bf6 --- /dev/null +++ b/programs/media/imgview/compile.bat @@ -0,0 +1,6 @@ +@echo off +@cl /c /O2 /nologo main.cpp kosSyst.cpp mcsmemm.cpp formats\pcx.cpp formats\bmp.cpp formats\tga.cpp dlgopen.cpp +@link /nologo /entry:crtStartUp /subsystem:native /base:0 /fixed /align:16 /nodefaultlib main.obj kosSyst.obj mcsmemm.obj pcx.obj bmp.obj tga.obj dlgopen.obj +@tools\pe2kos main.exe imgview.kos PARAM +@erase main.obj,kosSyst.obj,mcsmemm.obj,pcx.obj,bmp.obj,tga.obj,KosFile.obj,main.exe,dlgopen.obj +pause \ No newline at end of file diff --git a/programs/media/imgview/dlgopen.cpp b/programs/media/imgview/dlgopen.cpp new file mode 100644 index 0000000000..2747f61de2 --- /dev/null +++ b/programs/media/imgview/dlgopen.cpp @@ -0,0 +1,107 @@ +#include "kosSyst.h" + +char* DialogOpenFile(void (*draw)()) +{ + sProcessInfo proc; + kosFileInfo fi; + char param[6]; + int i; + Dword pID,msg_num=0; + char path[1040]; + Byte* pPath=(Byte*)&path; + + //Параметры запуска X-TREE + kos_ProcessInfo(&proc,-1); + pID=proc.processInfo.PID; + for(i=3;i!=-1;i--) + { + param[i]=(char)('0'+(pID % 10)); + pID=pID/10; + } + param[4]=(char)0x20; + param[5]='O'; + param[6]=(char)0; + //IPC + ((Dword*)pPath)[0] = 0; + ((Dword*)pPath)[1] = 8; + + Dword retval; + __asm + { + mov eax,60 + mov ebx,1 + mov ecx,pPath + mov edx,1040 + int 40h + } + + sprintf(fi.fileURL,"/sys/sysxtree"); + fi.rwMode = 7; + fi.OffsetLow = 0; + fi.OffsetHigh = (Dword)param; + fi.dataCount = 0; + fi.bufferPtr = 0; + int dlg_pID=kos_FileSystemAccess(&fi); + if (dlg_pID<=0) return 0; + + //kos_SetMaskForEvents(0x47); + kos_SetMaskForEvents(0x67); + //draw(); + + Dword btnID; + Byte keyCode; + + for(;;) + { +get_next_event: + //События + switch (kos_WaitForEvent(50)) + { + case 1: + draw(); + break; + case 2: + kos_GetKey(keyCode); + break; + case 3: + kos_GetButtonID(btnID); + break; + case 7: + if (msg_num==0) + { + ((Dword*)pPath)[0] = 0; + ((Dword*)pPath)[1] = 8; + ((Dword*)pPath)[2] = 0; + ((Dword*)pPath)[3] = 0; + ((Dword*)pPath)[4] = 0; + msg_num=1; + draw(); + } else { + return (char*)pPath+16; + } + break; + default: + //Жив ли еще X-TREE? + if (msg_num) + { + int proc_count=kos_ProcessInfo(&proc,-1); + for(i=1;i<=proc_count;i++) + { + kos_ProcessInfo(&proc,i); + if (proc.processInfo.PID==dlg_pID) + { + if (proc.processInfo.slot_state==9) + { + return 0; + } else { + goto get_next_event; + } + } + } + return 0; + } + break; + } + } + return 0; +} \ No newline at end of file diff --git a/programs/media/imgview/dlgopen.h b/programs/media/imgview/dlgopen.h new file mode 100644 index 0000000000..70596f7b65 --- /dev/null +++ b/programs/media/imgview/dlgopen.h @@ -0,0 +1 @@ +char* DialogOpenFile(void (*draw)()); \ No newline at end of file diff --git a/programs/media/imgview/formats/bmp.cpp b/programs/media/imgview/formats/bmp.cpp new file mode 100644 index 0000000000..c58b579e5e --- /dev/null +++ b/programs/media/imgview/formats/bmp.cpp @@ -0,0 +1,122 @@ +#include "..\kosSyst.h" +#include "bmp.h" + +int BMPFile::LoadBMPFile(Byte* filebuff, Dword filesize) +{ + Dword offset; + + memcpy((Byte*)&Bmp_head,(Byte*)filebuff,sizeof(tagBITMAPFILEHEADER)); + memcpy((Byte*)&Info_head,(Byte*)filebuff+14,sizeof(tagBITMAPINFOHEADER)); + + width=Info_head.biWidth; + height=Info_head.biHeight; + offset=(Dword)Bmp_head.bfOffbits; + + int state=0; + if (Bmp_head.bfType==0x4d42 && !Info_head.biCompression) + { + Byte* cBuffer; + Byte* pImg; + Byte* pPal; + Dword x,y; + Byte r; + Dword s,p; + Dword cWidth; + int i; + + buffer=kos_GetMemory(width*height*3); + pImg=filebuff+offset; + pPal=filebuff+53; + + int align_bytes = (4 - ((width * 3) % 4)) % 4; + Dword bpp = Info_head.biBitCount; + + switch(Info_head.biBitCount) + { + /* 16,24,32-bit decoding */ + case 32: + case 24: + case 16: + for(y=height-1;y!=-1;y--) + { + for(x=0;x>5) & 31)<<3; + *(cBuffer+2)=(Byte)((*(Word*)(pImg)>>10) & 31)<<3; + } else { + *(cBuffer+0)=*(pImg+0); + *(cBuffer+1)=*(pImg+1); + *(cBuffer+2)=*(pImg+2); + } + pImg=pImg+Info_head.biBitCount/8; + } + pImg=pImg+align_bytes; + } + break; + /* 8-bit decoding */ + case 8: + for(y=height-1;y!=-1;y--) + { + for(x=0;x=width) break; + __asm + { + mov eax,s + mov ecx,bpp + rol eax,cl + mov s,eax + mov ebx,1 + shl ebx,cl + dec ebx + and eax,ebx + mov p,eax + } + cBuffer=buffer+(y*width*3)+x*3; + *(cBuffer+0)=(Byte)(pPal[p*4+1]); + *(cBuffer+1)=(Byte)(pPal[p*4+2]); + *(cBuffer+2)=(Byte)(pPal[p*4+3]); + x++; + } + } + } + break; + default: + state=1; + break; + } + } else { + state=1; + } + return state; +} \ No newline at end of file diff --git a/programs/media/imgview/formats/bmp.h b/programs/media/imgview/formats/bmp.h new file mode 100644 index 0000000000..8d4be3ffec --- /dev/null +++ b/programs/media/imgview/formats/bmp.h @@ -0,0 +1,45 @@ +#pragma pack(push, 1) +typedef struct tagBITMAPFILEHEADER +{ + Word bfType; //тип файла (для битового образа - BM) + Dword bfSize; //размер файла в dword + Word bfReserved1; //не используется + Word bfReserved2; //не используется + Dword bfOffbits; //смещение данных битового образа от заголовка в байтах +} tagBITMAPFILEHEADER; + +typedef struct tagBITMAPINFOHEADER +{ + Dword biSize; //число байт, занимаемых структурой BITMAPINFOHEADER + Dword biWidth; //ширина битового образа в пикселах + Dword biHeight; //высота битового образа в пикселах + Word biPlanes; //число битовых плоскостей устройства + Word biBitCount; //число битов на пиксель + Dword biCompression; //тип сжатия + Dword biSizeImage; //размер картинки в байтах + Dword biXPelsPerMeter; //горизонтальное разрешение устройства, пиксел/м + Dword biYPelPerMeter; //вертикальное разрешение устройства, пиксел/м + Dword biClrUsed; //число используемых цветов + Dword biClrImportant; //число "важных" цветов +} tagBITMAPINFOHEADER; + +typedef struct tagRGBQUAD +{ + Byte rgbBlue; + Byte rgbGreen; + Byte rgbRed; + Byte rgbReserved; +} tagRGBQUAD; +#pragma pack(pop) + +class BMPFile +{ +protected: + tagBITMAPFILEHEADER Bmp_head; + tagBITMAPINFOHEADER Info_head; +public: + Dword width; + Dword height; + Byte* buffer; + int BMPFile::LoadBMPFile(Byte* filebuff, Dword filesize); +}; \ No newline at end of file diff --git a/programs/media/imgview/formats/pcx.cpp b/programs/media/imgview/formats/pcx.cpp new file mode 100644 index 0000000000..be67420300 --- /dev/null +++ b/programs/media/imgview/formats/pcx.cpp @@ -0,0 +1,55 @@ +#include "..\kosSyst.h" +#include "pcx.h" + +int PCXFile::LoadPCXFile(Byte* filebuff, Dword filesize) +{ + memcpy((Byte*)&Pcx_head,(Byte*)filebuff,sizeof(PCXHeader)); + + int state=0; + if (Pcx_head.bManufacturer==0x0a && Pcx_head.bVersion==0x05) + { + width=Pcx_head.dwWidth-Pcx_head.dwX+1; + height=Pcx_head.dwHeight-Pcx_head.dwY+1; + buffer=kos_GetMemory(width*height*3); + + Byte* pPal=filebuff+filesize-768; + Byte* pImg=filebuff+128; + Byte* cBuffer=(Byte*)buffer; + if (Pcx_head.bNPlanes==1) + { + /* 8-bit decoding */ + Dword y,i; + Byte cur_byte,counter; + Dword cWidth; + + for(y=0;y=192) + { + counter=(cur_byte & 0x3F); + cur_byte=*(pImg); pImg++; + } + for(i=0;i= 32) sm=height-1; else sm=0; + // Изображение с палитрой (палитра 24 или 32-битная) + if (Tga_head.ImageTypeCode==1) + { + if (Tga_head.ColorMapEntrySize>=24) + { + buffer=kos_GetMemory(width*height*3); + int bpp=Tga_head.ColorMapEntrySize/8; + for(y=height-1;y!=-1;y--) + { + for(x=0;x>5) & 31)<<3; + *(cBuffer+2)=(Byte)((*(Word*)(pImg)>>10) & 31)<<3; + pImg=pImg+2; + } + } + state=0; + break; + } + } + // Монохромное изображение + else if (Tga_head.ImageTypeCode==3) + { + switch (Tga_head.ImagePixelSize) + { + case 8: + buffer=kos_GetMemory(width*height*3); + for(y=height-1;y!=-1;y--) + { + for(x=0;x12Z700mPzE%*Y@C7I%QkgE>&*{p(L#pg2DLKxzD%vFl$`TM9wT zs>*;22niQNa|^#!oA6hsYNF^YbOC{U5();R0KaX=CcLG%MXg;W3f zaJ5ynWk79)v+RKg$oTx@E08QW*ZT9%FQ9&)0-$D``hm^^Dth<)zFeg;Q2)QLumAu2 z3`Yd)hx`BkoYQ2%P%injs8iJCWHq^&>07!={FQO3NRh^B_h59YYcV>H_Lz F006o?1h4=A literal 0 HcmV?d00001 diff --git a/programs/media/imgview/img/btn_next.bmp b/programs/media/imgview/img/btn_next.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9d5a175a9ba77910ae50508615c6ea6f22b19a81 GIT binary patch literal 1398 zcmbu9J4gdT5QfKq7FHGtR+eIu)>%1RrpM6l4pLP3Ish=qcfLKJ*k z2Oo`Em?}0Yf&@fuB)5Kdb1avzCq|dK&Ft-d|2+0cZ+f;-g3-;~#nTo(4bmRG?+N#V zML3m9<-+a7Wp?B4V685Lf)#$i@ai=vSos^Q!C+(g{XU7BGdnkbm=^40K(0qZW0@W9 zM6O1~!E^3>NNy$^mQDE?MI~x^;t*5e+_*!615pVFuW-ef=f$MW!Wi?OztZJis>P;I z#XnBV{Ztqe!22j!i6~EBC{QJ8`NF)Y3V@E6?NJKBxA9rV@~=yRM1IBxbWq6CTnE18 zsUnvDT9>yKDK04Q8LvWofM4;s$tJVejKt?EfDadsmTfsUer*1<#7}jr)npRz-op-w z*m5k-6}tN$^2hyVH|d>?X(Dt46&2Fk;RB21+2GEAk?<{((2m%?@(EfPr|SOf1`?PF r647$#2t7X?tb${C6;c&DTlJ{pjvqbov+wi&{r@3?N+4F3LBYy5@L$1_ literal 0 HcmV?d00001 diff --git a/programs/media/imgview/img/btn_open.bmp b/programs/media/imgview/img/btn_open.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5bdc31b873f1c7968c16e8d0a7c325ca919c2543 GIT binary patch literal 1398 zcmb`HKS%;$7{;%mwIm1{qoG0?nrf90X|Ql;kqC?m8X69QaJA_j$jA8yQ<_<@C=GYCo<{<7(l$ z^nH)YNZ)E~T*P*&9(CmCwrx`AAR0(FPwo`rR{fBNts#ZJn^ zM3#S-{MZK!N4H0FD~fu+B}91Lt-{$Pm0!DAE}@D;3T6JS?_b*mct!^8hwRge>mm-e!Pl;wc>b0TTD3+NngVs-w|IF)?yOj pjv(!D=DahWKd*)@5b+4Vl6fOuHZ_=N{=fep=ve_-q5%pleFI?W!Vdrd literal 0 HcmV?d00001 diff --git a/programs/media/imgview/img/template.bmp b/programs/media/imgview/img/template.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f33948c438a149a020797f94cc427459860800ab GIT binary patch literal 1398 zcmZ?rEn{T>12Z700mPzE%*Y@C7I%QkgE>&*{pzzfg}Xf1=Py`0Ec{+ AYXATM literal 0 HcmV?d00001 diff --git a/programs/media/imgview/kosSyst.cpp b/programs/media/imgview/kosSyst.cpp new file mode 100644 index 0000000000..ff54e99ead --- /dev/null +++ b/programs/media/imgview/kosSyst.cpp @@ -0,0 +1,921 @@ +#include "kosSyst.h" +#include "stdarg.h" + +#define atexitBufferSize 32 + + +char pureCallMessage[] = "PURE function call!"; + +char *kosExePath = NULL; + +int abs(int value) +{ + if (value<0) value=0-value; + return value; +} + +// +void (__cdecl *atExitList[atexitBufferSize])(); +int atExitFnNum = 0; +// +int __cdecl atexit( void (__cdecl *func )( void )) +{ + // + if ( atExitFnNum < atexitBufferSize ) + { + // + atExitList[atExitFnNum++] = func; + return 0; + } + else + { + return 1; + } +} + + +// +Dword RandomSeed = 1; +// +void rtlSrand( Dword seed ) +{ + RandomSeed = seed; +} +// +Dword rtlRand( void ) +{ + //маска 0x80000776 + + Dword dwi, i; + + for ( i = 0; i < 32; i++ ) + { + + dwi = RandomSeed & 0x80000776; + + __asm{ + mov eax, dwi + mov edx, eax + bswap eax + xor eax, edx + xor al, ah + setpo al + movzx eax, al + mov dwi, eax + } + + RandomSeed = ( RandomSeed << 1 ) | ( dwi & 1 ); + } + + return RandomSeed; +} + +#if _MSC_VER >= 1400 +// +void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ) +{ + __asm{ + mov edi, dst + mov eax, dst + mov esi, src + mov ecx, bytesCount + rep movsb + } +} + +// +void memset( Byte *dst, Byte filler, Dword count ) +{ + // + __asm{ + mov edi, dst + mov al, filler + mov ecx, count + rep stosb + } +} +#endif + +// +Dword rtlInterlockedExchange( Dword *target, Dword value ) +{ +// Dword result; + + // + __asm{ + mov eax, value + mov ebx, target + xchg eax, [ebx] +// mov result, eax + } + // +// return result; +} + + +////////////////////////////////////////////////////////////////////// +// +// копирование строки +// + +char * __cdecl strcpy( char *target, const char *source ) +{ + char *result = target; + + while( target[0] = source[0] ) + { + target++; + source++; + } + + return result; +} + + +////////////////////////////////////////////////////////////////////// +// +// реверсивный поиск символа +// + +char * __cdecl strrchr( const char * string, int c ) +{ + char *cPtr; + + // + for ( cPtr = (char *)string + strlen( string ); cPtr >= string; cPtr-- ) + { + // + if ( *cPtr == c ) return cPtr; + } + // + return NULL; +} + + +////////////////////////////////////////////////////////////////////// +// +// определение длины строки +// + +int __cdecl strlen( const char *line ) +{ + int i; + + for( i=0; line[i] != 0; i++ ); + return i; +} + + + +////////////////////////////////////////////////////////////////////// +// +// Сравнение строк +// + +int strcmp(char* string1, char* string2) +{ + Dword retval; + if (strlen(string1)==strlen(string2)) + { + __asm + { + mov dword ptr [retval],0 + mov esi,string1 + mov edi,string2 + next_char: + mov al,byte ptr [esi] + mov bl,byte ptr [edi] + inc esi + inc edi + cmp bl,0 + je fin + cmp al,bl + je next_char + jmp not_equal + fin: + mov dword ptr [retval],1 + not_equal: + } + return retval; + } else { + return 0; + } +} + + +////////////////////////////////////////////////////////////////////// +// +// перевод шестнадцатиричного числа в символ +// + +unsigned int num2hex( unsigned int num ) +{ + if( num < 10 ) + return num + '0'; + return num - 10 + 'A'; +} + + + +////////////////////////////////////////////////////////////////////// +// +// перевод строки в нижний регистр +// + +void lcase(char* string) +{ + int i; + char chr; + for(i=0;i=65 && chr<=90) chr=chr+32; //a-z + if (chr>=128 && chr<=143) chr=chr+32; //а-п + if (chr>=144 && chr<=159) chr=chr+80; //р-я + if (chr==240) chr=241; //ё + ((char*)string)[i]=chr; + } +} + + +////////////////////////////////////////////////////////////////////// +// +// вывод строки на печать +// + +Dword dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000, + 10000, 1000, 100, 10, 0 }; + +// +void sprintf( char *Str, char* Format, ... ) +{ + int i, fmtlinesize, j, k, flag; + Dword head, tail; + char c; + va_list arglist; + // + va_start(arglist, Format); + + // + fmtlinesize = strlen( Format ); + // + if( fmtlinesize == 0 ) return; + + // + for( i = 0, j = 0; i < fmtlinesize; i++ ) + { + // + c = Format[i]; + // + if( c != '%' ) + { + Str[j++] = c; + continue; + } + // + i++; + // + if( i >= fmtlinesize ) break; + + // + flag = 0; + // + c = Format[i]; + // + switch( c ) + { + // + case '%': + Str[j++] = c; + break; + // вывод строки + case 'S': + Byte* str; + str = va_arg(arglist, Byte*); + for( k = 0; ( c = str[k] ) != 0; k++ ) + { + Str[j++] = c; + } + break; + // вывод байта + case 'B': + k = va_arg(arglist, int) & 0xFF; + Str[j++] = num2hex( ( k >> 4 ) & 0xF ); + Str[j++] = num2hex( k & 0xF ); + break; + // вывод символа + case 'C': + Str[j++] = va_arg(arglist, int) & 0xFF; + break; + // вывод двойного слова в шестнадцатиричном виде + case 'X': + Dword val; + val = va_arg(arglist, Dword); + for( k = 7; k >= 0; k-- ) + { + // + c = num2hex ( ( val >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + if( flag == 0 ) Str[j++] = '0'; + break; + // вывод двойного слова в десятичном виде + case 'U': + head = va_arg(arglist, Dword); + tail = 0; + for( k = 0; dectab[k] != 0; k++ ) + { + tail = head % dectab[k]; + head /= dectab[k]; + c = head + '0'; + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + // + head = tail; + } + // + c = head + '0'; + Str[j++] = c; + break; + // вывод 64-битного слова в шестнадцатиричном виде + case 'Q': + unsigned int low_dword, high_dword; + low_dword = va_arg(arglist, unsigned int); + high_dword = va_arg(arglist, unsigned int); + for( k = 7; k >= 0; k-- ) + { + // + c = num2hex ( ( ( high_dword + 1) >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + for( k=7; k >= 0; k-- ) + { + // + c = num2hex ( ( low_dword >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + if( flag == 0 ) Str[j++] = '0'; + // + break; + // + default: + break; + } + } + // + Str[j] = 0; +} + + +// функция -1 завершения процесса +void kos_ExitApp() +{ + int i; + + // + for ( i = atExitFnNum - 1; i >= 0; i-- ) + { + // + atExitList[i](); + } + // + __asm{ + mov eax, -1 + int 0x40 + } +} + + +// функция 0 +void kos_DefineAndDrawWindow( + Word x, Word y, + Word sizeX, Word sizeY, + Byte mainAreaType, + Dword mainAreaColour, + Byte headerType, + Dword headerColour, + Dword borderColour + ) +{ + Dword arg1, arg2, arg3, arg4; + + // + arg1 = ( x << 16 ) + sizeX; + arg2 = ( y << 16 ) + sizeY; + arg3 = ( mainAreaType << 24 ) | mainAreaColour; + arg4 = ( headerType << 24 ) | headerColour; + // + __asm{ + mov eax, 0 + mov ebx, arg1 + mov ecx, arg2 + mov edx, arg3 + mov esi, arg4 + mov edi, borderColour + int 0x40 + } +} + + +// функция 1 поставить точку +void kos_PutPixel( Dword x, Dword y, Dword colour ) +{ + // + __asm{ + mov eax, 1 + mov ebx, x + mov ecx, y + mov edx, colour + int 0x40 + } +} + + +// функция 2 получить код нажатой клавиши +bool kos_GetKey( Byte &keyCode ) +{ + Dword result; + + // + __asm{ + mov eax, 2 + int 0x40 + mov result, eax + } + // + keyCode = result >> 8; + // + return ( result & 0xFF ) == 0; +} + + +// функция 3 получить время +Dword kos_GetSystemClock() +{ +// Dword result; + + // + __asm{ + mov eax, 3 + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// функция 4 +void kos_WriteTextToWindow( + Word x, + Word y, + Byte fontType, + Dword textColour, + char *textPtr, + Dword textLen + ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | y; + arg2 = ( fontType << 24 ) | textColour; + // + __asm{ + mov eax, 4 + mov ebx, arg1 + mov ecx, arg2 + mov edx, textPtr + mov esi, textLen + int 0x40 + } +} + + +// функция 5 пауза, в сотых долях секунды +void kos_Pause( Dword value ) +{ + // + __asm{ + mov eax, 5 + mov ebx, value + int 0x40 + } +} + + +// функция 7 нарисовать изображение +void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y ) +{ + Dword arg1, arg2; + + // + arg1 = ( sizeX << 16 ) | sizeY; + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 7 + mov ebx, imagePtr + mov ecx, arg1 + mov edx, arg2 + int 0x40 + } +} + + + +// функция 8 определить кнопку +void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | sizeX; + arg2 = ( y << 16 ) | sizeY; + // + __asm{ + mov eax, 8 + mov ebx, arg1 + mov ecx, arg2 + mov edx, buttonID + mov esi, colour + int 0x40 + } +} + + +// функция 9 - информация о процессе +Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID ) +{ +// Dword result; + + // + __asm{ + mov eax, 9 + mov ebx, targetPtr + mov ecx, processID + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// функция 10 +Dword kos_WaitForEvent() +{ +// Dword result; + + __asm{ + mov eax, 10 + int 0x40 +// mov result, eax + } + +// return result; +} + + +// функция 11 +Dword kos_CheckForEvent() +{ +// Dword result; + + __asm{ + mov eax, 11 + int 0x40 +// mov result, eax + } + +// return result; +} + + +// функция 12 +void kos_WindowRedrawStatus( Dword status ) +{ + __asm{ + mov eax, 12 + mov ebx, status + int 0x40 + } +} + + +// функция 13 нарисовать полосу +void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | sizeX; + arg2 = ( y << 16 ) | sizeY; + // + __asm{ + mov eax, 13 + mov ebx, arg1 + mov ecx, arg2 + mov edx, colour + int 0x40 + } +} + + +// функция 17 +bool kos_GetButtonID( Dword &buttonID ) +{ + Dword result; + + // + __asm{ + mov eax, 17 + int 0x40 + mov result, eax + } + // + buttonID = result >> 8; + // + return (result & 0xFF) == 0; +} + + +// функция 23 +Dword kos_WaitForEvent( Dword timeOut ) +{ +// Dword result; + + __asm{ + mov eax, 23 + mov ebx, timeOut + int 0x40 +// mov result, eax + } + +// return result; +} + + +// получение информации о состоянии "мыши" функция 37 +void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY ) +{ + Dword mB; + Word curX; + Word curY; + sProcessInfo sPI; + + // + __asm{ + mov eax, 37 + mov ebx, 1 + int 0x40 + mov curY, ax + shr eax, 16 + mov curX, ax + mov eax, 37 + mov ebx, 2 + int 0x40 + mov mB, eax + } + // + kos_ProcessInfo( &sPI ); + // + buttons = mB; + cursorX = curX - sPI.processInfo.left; + cursorY = curY - sPI.processInfo.top; +} + + +// функция 40 установить маску событий +void kos_SetMaskForEvents( Dword mask ) +{ + // + __asm{ + mov eax, 40 + mov ebx, mask + int 0x40 + } +} + + +// функция 47 вывести в окно приложения число +void kos_DisplayNumberToWindow( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + eNumberBase nBase, + bool valueIsPointer + ) +{ + Dword arg1, arg2; + + // + arg1 = ( valueIsPointer ? 1 : 0 ) | + ( ((Byte)nBase) << 8 ) | + ( ( digitsNum & 0x1F ) << 16 ); + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 47 + mov ebx, arg1 + mov ecx, value + mov edx, arg2 + mov esi, colour + int 0x40 + } +} + + +// функция 70 доступ к файловой системе +Dword kos_FileSystemAccess( kosFileInfo *fileInfo ) +{ +// Dword result; + + // + __asm{ + mov eax, 70 + mov ebx, fileInfo + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// функция 63 вывод символя в окно отладки +void kos_DebugOutChar( char ccc ) +{ + // + __asm{ + mov eax, 63 + mov ebx, 1 + mov cl, ccc + int 0x40 + } +} + + +// функция 66 режим получения данных от клавиатуры +void kos_SetKeyboardDataMode( Dword mode ) +{ + // + __asm{ + mov eax, 66 + mov ebx, 1 + mov ecx, mode + int 0x40 + } +} + + +// вывод строки в окно отладки +void rtlDebugOutString( char *str ) +{ + // + for ( ; str[0] != 0; str++ ) + { + kos_DebugOutChar( str[0] ); + } + // + kos_DebugOutChar( 13 ); + kos_DebugOutChar( 10 ); +} + + +// функция 64 изменение количества памяти, выделенной для программы +bool kos_ApplicationMemoryResize( Dword targetSize ) +{ + Dword result; + + // + __asm{ + mov eax, 64 + mov ebx, 1 + mov ecx, targetSize + int 0x40 + mov result, eax + } + // + return result == 0; +} + + +// функция 67 изменить параметры окна, параметр == -1 не меняется +void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY ) +{ + // + __asm{ + mov eax, 67 + mov ebx, x + mov ecx, y + mov edx, sizeX + mov esi, sizeY + int 0x40 + } +} + + + +Byte* kos_GetMemory(Dword count) +{ + __asm + { + mov eax,68 + mov ebx,12 + mov ecx,count + int 40h + } +} + +Dword kos_FreeMemory(Byte* pMemory) +{ + __asm + { + mov eax,68 + mov ebx,13 + mov ecx,pMemory + int 40h + } +} + +// вызов абстрактного метода +int __cdecl _purecall() +{ + rtlDebugOutString( pureCallMessage ); + kos_ExitApp(); + return 0; +} + + +// вызов статических инициализаторов +// заодно инициализация генератора случайных чисел +//#pragma section(".CRT$XCA",long,read,write) +//#pragma section(".CRT$XCZ",long,read,write) +#pragma data_seg(".CRT$XCA") +#pragma data_seg(".CRT$XCZ") +typedef void (__cdecl *_PVFV)(void); +__declspec(allocate(".CRT$XCA")) _PVFV __xc_a[1] = { NULL }; +__declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[1] = { NULL }; +// +#pragma comment(linker, "/merge:.CRT=.rdata") +// +void crtStartUp() +{ + // вызываем инициализаторы по списку, NULL'ы игнорируем + for ( _PVFV *pbegin = __xc_a; pbegin < __xc_z; pbegin++ ) + { + // + if ( *pbegin != NULL ) + (**pbegin)(); + } + // инициализируем генератор случайных чисел + rtlSrand( kos_GetSystemClock() ); + // путь к файлу процесса + kosExePath = *((char **)0x20); + // вызов главной функции приложения + kos_Main(); + // выход + kos_ExitApp(); +} + + diff --git a/programs/media/imgview/kosSyst.h b/programs/media/imgview/kosSyst.h new file mode 100644 index 0000000000..c9804f386b --- /dev/null +++ b/programs/media/imgview/kosSyst.h @@ -0,0 +1,203 @@ +typedef unsigned __int32 Dword; +typedef unsigned __int16 Word; +typedef unsigned __int8 Byte; +//typedef unsigned __int32 size_t; + +#define NULL 0 + +#define MAX_PATH 256 + +#define FO_READ 0 +#define FO_WRITE 2 + +#define EM_WINDOW_REDRAW 1 +#define EM_KEY_PRESS 2 +#define EM_BUTTON_CLICK 4 +#define EM_APP_CLOSE 8 +#define EM_DRAW_BACKGROUND 16 +#define EM_MOUSE_EVENT 32 +#define EM_IPC 64 +#define EM_NETWORK 256 + +#define KM_CHARS 0 +#define KM_SCANS 1 + +#define WRS_BEGIN 1 +#define WRS_END 2 + +#define PROCESS_ID_SELF -1 + +//#define abs(a) (a<0?0-a:a) + +extern "C" double acos(double x); +extern "C" double asin(double x); +extern "C" double floor(double x); +extern "C" double round(double x); +#pragma function(acos,asin) +#if _MSC_VER > 1200 +#pragma function(floor) +#endif + + +struct kosFileInfo +{ + Dword rwMode; + Dword OffsetLow; + Dword OffsetHigh; + Dword dataCount; + Byte *bufferPtr; + char fileURL[MAX_PATH]; +}; + + +struct RGB +{ + Byte b; + Byte g; + Byte r; + // + RGB() {}; + // + RGB( Dword value ) + { + r = (Byte)(value >> 16); + g = (Byte)(value >> 8); + b = (Byte)value; + }; + // + bool operator != ( RGB &another ) + { + return this->b != another.b || this->g != another.g || this->r != another.r; + }; + // + bool operator == ( RGB &another ) + { + return this->b == another.b && this->g == another.g && this->r == another.r; + }; +}; + + +union sProcessInfo +{ + Byte rawData[1024]; + #pragma pack(push, 1) + struct + { + Dword cpu_usage; + Word window_stack_position; + Word window_stack_value; + Word reserved1; + char process_name[12]; + Dword memory_start; + Dword used_memory; + Dword PID; + Dword left; + Dword top; + Dword width; + Dword height; + Word slot_state; + Word reserved2; + Dword work_left; + Dword work_top; + Dword work_width; + Dword work_height; + Byte window_state; + } processInfo; + #pragma pack(pop) +}; + +// +extern char *kosExePath; +// +int abs(int value); +// +void crtStartUp(); +// +int __cdecl _purecall(); +// +int __cdecl atexit( void (__cdecl *func )( void )); +// +void rtlSrand( Dword seed ); +Dword rtlRand( void ); +// +char * __cdecl strcpy( char *target, const char *source ); +int __cdecl strlen( const char *line ); +char * __cdecl strrchr( const char * string, int c ); +void lcase(char* string); +int strcmp(char* string1, char* string2); + +#if _MSC_VER < 1400 +extern "C" void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ); +extern "C" void memset( Byte *dst, Byte filler, Dword count ); +#pragma intrinsic(memcpy,memset) +#else +void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ); +void memset( Byte *dst, Byte filler, Dword count ); +#endif + +void sprintf( char *Str, char* Format, ... ); +// +Dword rtlInterlockedExchange(Dword *target, Dword value); +// функция -1 завершения процесса +void kos_ExitApp(); +// функция 0 +void kos_DefineAndDrawWindow(Word x, Word y, Word sizeX, Word sizeY,Byte mainAreaType, Dword mainAreaColour,Byte headerType, Dword headerColour, Dword borderColour); +// функция 1 поставить точку +void kos_PutPixel( Dword x, Dword y, Dword colour); +// функция 2 получить код нажатой клавиши +bool kos_GetKey(Byte &keyCode); +// функция 3 получить время +Dword kos_GetSystemClock(); +// функция 4 +void kos_WriteTextToWindow(Word x, Word y,Byte fontType,Dword textColour,char *textPtr,Dword textLen); +// функция 7 нарисовать изображение +void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y); +// функция 8 определить кнопку +void kos_DefineButton(Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour); +// функция 5 пауза, в сотых долях секунды +void kos_Pause(Dword value); +// функция 9 - информация о процессе +Dword kos_ProcessInfo(sProcessInfo *targetPtr, Dword processID = PROCESS_ID_SELF); +// функция 10 +Dword kos_WaitForEvent(); +// функция 11 +Dword kos_CheckForEvent(); +// функция 12 +void kos_WindowRedrawStatus(Dword status ); +// функция 13 нарисовать полосу +void kos_DrawBar(Word x, Word y, Word sizeX, Word sizeY, Dword colour); +// функция 17 +bool kos_GetButtonID(Dword &buttonID); +// функция 23 +Dword kos_WaitForEvent(Dword timeOut); +// +enum eNumberBase +{ + nbDecimal = 0, + nbHex, + nbBin +}; +// получение информации о состоянии "мыши" функция 37 +void kos_GetMouseState(Dword & buttons, int & cursorX, int & cursorY); +// функция 40 установить маску событий +void kos_SetMaskForEvents(Dword mask); +// функция 47 вывести в окно приложения число +void kos_DisplayNumberToWindow(Dword value, Dword digitsNum, Word x, Word y, Dword colour, eNumberBase nBase = nbDecimal, bool valueIsPointer = false); +// функция 58 доступ к файловой системе +Dword kos_FileSystemAccess(kosFileInfo *fileInfo); +// функция 63 +void kos_DebugOutChar(char ccc); +// +void rtlDebugOutString(char *str); +// функция 64 изменить параметры окна, параметр == -1 не меняется +void kos_ChangeWindow(Dword x, Dword y, Dword sizeX, Dword sizeY); +// функция 67 изменение количества памяти, выделенной для программы +bool kos_ApplicationMemoryResize(Dword targetSize); +// функция 66 режим получения данных от клавиатуры +void kos_SetKeyboardDataMode(Dword mode); +// +Byte* kos_GetMemory(Dword count); +// +Dword kos_FreeMemory(Byte* pMemory); +// +void kos_Main(); diff --git a/programs/media/imgview/main.cpp b/programs/media/imgview/main.cpp new file mode 100644 index 0000000000..517fe1045b --- /dev/null +++ b/programs/media/imgview/main.cpp @@ -0,0 +1,575 @@ +#include "kosSyst.h" +#include "gfx.cpp" +#include "dlgopen.h" +#include "formats\pcx.h" +#include "formats\bmp.h" +#include "formats\tga.h" + +#define btn_open 10 +#define btn_prev 11 +#define btn_next 12 +#define btn_fit 13 + +#define scrl_up 30 +#define scrl_down 31 +#define scrl_left 32 +#define scrl_right 33 + +char params[2048] = "PARAM"; +const char header[] = "ImageView v 0.08"; +int image_opened=0; + +Byte* image_buffer=NULL; // Полное RAW-Изображение +Byte* img_cuted=NULL; // Усеченное RAW-изображение (используется при прокрутке или масштабировании) +Byte* cur_files=NULL; // Буфер для общего списка файлов текущей папки +Word* img_files=NULL; // Указатель массив со список граф.файлов в текущей папке +Dword cnt_imgfiles; // Количество элементов массива img_files[] +Dword cur_image; // Номер текущего изображения в массиве +char cur_folder[512]; // Путь к текущей папке с / на конце + +Dword image_width; +Dword image_height; +Dword old_status_size=0; + +char szStatus[256]; +bool scale=0; + + +sProcessInfo proc; +Dword img_area_left,img_area_top,img_area_width,img_area_height; +int vscrl_max=100,vscrl_value=0,vscrl_coord_x,vscrl_coord_y,vscrl_coord_min,vscrl_coord_max,vscrl_using=0; +int hscrl_max=100,hscrl_value=0,hscrl_coord_x,hscrl_coord_y,hscrl_coord_min,hscrl_coord_max,hscrl_using=0; +Dword width_old,height_old; + +/* Вырезает квадрат из изображения по координатам*/ +void GetRectImage(Byte* src, Byte* dst, Dword left,Dword top,Dword width,Dword height) +{ + int x,y; + int pImgS,pImgD=0; + + for(y=top;yimage_width) new_width=image_width; + if (new_height>image_height) new_height=image_height; + + ResizeImage(image_buffer,img_cuted,new_width,new_height); + /* Центрирование изображения */ + scale_left=(img_area_width/2)-(new_width/2); + scale_top=(img_area_height/2)-(new_height/2); + kos_PutImage((RGB*)img_cuted,new_width,new_height,img_area_left+scale_left,img_area_top+scale_top); + } +} + +void draw_window(void) +{ + kos_WindowRedrawStatus(1); + kos_DefineAndDrawWindow(0,0,450,350,0x33,0xEFEBEF,0,0,(Dword)header); + + //ToolBar + //open + kos_DefineButton(2,4,20,20,btn_open+0x40000000,0xEFEBEF); + kos_PutImage(tbOpen,21,21,2,4); + //prev + kos_DefineButton(25,4,20,20,btn_prev+0x40000000,0xEFEBEF); + kos_PutImage(tbPrev,21,21,25,4); + //next + kos_DefineButton(48,4,20,20,btn_next+0x40000000,0xEFEBEF); + kos_PutImage(tbNext,21,21,48,4); + //fit image + kos_DefineButton(71,4,20,20,btn_fit+0x40000000,0xEFEBEF); + kos_PutImage(tbFit,21,21,71,4); + + //Lines + kos_ProcessInfo(&proc,-1); + kos_DrawBar(2,30,proc.processInfo.work_width-3,1,0x94AECE); + + //Scroll controls + //vertical scroll bar + vscrl_coord_x=proc.processInfo.work_width-16; + vscrl_coord_max=proc.processInfo.work_height-46; + kos_DrawBar(proc.processInfo.work_width-16,33,15,proc.processInfo.work_height-79,0xDADADA); + kos_DefineButton(proc.processInfo.work_width-16,33,14,14,scrl_up+0x40000000,0xEFEBEF); + kos_DefineButton(proc.processInfo.work_width-16,proc.processInfo.work_height-46,14,14,scrl_down+0x40000000,0xEFEBEF); + kos_PutImage(arrow_up,15,15,proc.processInfo.work_width-16,33); + kos_PutImage(arrow_down,15,15,proc.processInfo.work_width-16,proc.processInfo.work_height-46); + kos_PutImage(scroll_v,15,35,vscrl_coord_x,vscrl_coord_y); + + + //horisontal scroll bar + hscrl_coord_y=proc.processInfo.work_height-31; + hscrl_coord_max=proc.processInfo.work_width-31; + kos_DrawBar(2,proc.processInfo.work_height-31,proc.processInfo.work_width-18,15,0xDADADA); + kos_DefineButton(2,proc.processInfo.work_height-31,14,14,scrl_left+0x40000000,0xEFEBEF); + kos_DefineButton(proc.processInfo.work_width-31,proc.processInfo.work_height-31,14,14,scrl_right+0x40000000,0xEFEBEF); + kos_PutImage(arrow_left,15,15,2,proc.processInfo.work_height-31); + kos_PutImage(arrow_right,15,15,proc.processInfo.work_width-31,proc.processInfo.work_height-31); + kos_PutImage(scroll_h,35,15,hscrl_coord_x,hscrl_coord_y); + + img_area_left=2; + img_area_top=33; + img_area_width=proc.processInfo.work_width-img_area_left-3-16; + img_area_height=proc.processInfo.work_height-img_area_top-3-16-15; + + kos_WriteTextToWindow(2,proc.processInfo.work_height-12, 0x80, 0, szStatus, 0); + + if (img_area_widthimage_width) win_width=image_width+img_area_left+3+16+10; else win_width=scr_right-scr_left+1; + 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; + + if (win_width<150) win_width=150; + if (win_height<160) win_height=160; + + img_cuted=kos_GetMemory(image_width*image_height*3); + kos_ChangeWindow(scr_left,scr_top,win_width,win_height); + + if (img_area_width= vscrl_coord_max) break; + set_vscroll_values(vscrl_max, ((vscrl_coord_y + 2 - vscrl_coord_min) * vscrl_max) / (vscrl_coord_max - vscrl_coord_min - 35)); + break; +*/ + + case btn_fit: + scale = scale ? 0 : 1; + draw_window(); + break; + + } + break; + + case 6: + default: + kos_GetMouseState(mButton,mX,mY); + //Вертикальная прокрутка + if (mButton==1) + { + if (vscrl_using) + { + kos_DrawBar(vscrl_coord_x,vscrl_coord_y,15,35,0xDADADA); + if (vscrl_coord_y+mY-mYOldvscrl_coord_max) { + vscrl_value=vscrl_max; + vscrl_coord_y=vscrl_coord_max-35; + } else { + vscrl_value=(((vscrl_coord_y-vscrl_coord_min)*vscrl_max)/(vscrl_coord_max-vscrl_coord_min-35)); + vscrl_coord_y=vscrl_coord_y+mY-mYOld; + mYOld=mY; + } + kos_PutImage(scroll_v,15,35,vscrl_coord_x,vscrl_coord_y); + draw_image(); + } else { + if (mY>=vscrl_coord_y && mY<=vscrl_coord_y+35 && mX>=vscrl_coord_x && mX<=vscrl_coord_x+15) + { + vscrl_using=1; + mYOld=mY; + } + } + } else if(mButton==0) { + if (vscrl_using) {vscrl_using=0; draw_image();} + } + //Горизонтальная прокрутка + if (mButton==1) + { + if (hscrl_using) + { + kos_DrawBar(hscrl_coord_x,hscrl_coord_y,35,15,0xDADADA); + if (hscrl_coord_x+mX-mXOldhscrl_coord_max) { + hscrl_value=hscrl_max; + hscrl_coord_x=hscrl_coord_max-35; + } else { + hscrl_value=(((hscrl_coord_x-hscrl_coord_min)*hscrl_max)/(hscrl_coord_max-hscrl_coord_min-35)); + hscrl_coord_x=hscrl_coord_x+mX-mXOld; + mXOld=mX; + } + kos_PutImage(scroll_h,35,15,hscrl_coord_x,hscrl_coord_y); + draw_image(); + } else { + if (mX>=hscrl_coord_x && mX<=hscrl_coord_x+35 && mY>=hscrl_coord_y && mY<=hscrl_coord_y+15) + { + hscrl_using=1; + mXOld=mX; + } + } + } else if(mButton==0) { + if (hscrl_using) {hscrl_using=0; draw_image();} + } + + break; + } + } +} \ No newline at end of file diff --git a/programs/media/imgview/mcsmemm.cpp b/programs/media/imgview/mcsmemm.cpp new file mode 100644 index 0000000000..20feab80f6 --- /dev/null +++ b/programs/media/imgview/mcsmemm.cpp @@ -0,0 +1,329 @@ +// memman.cpp : Defines the entry point for the console application. +// + +#include "kosSyst.h" +#include "mcsmemm.h" + + +void * __cdecl operator new ( size_t count, size_t element_size ) +{ + return allocmem( (Dword)(count * element_size) ); +} + +void * __cdecl operator new [] ( size_t amount ) +{ + return allocmem( (Dword)amount ); +} + +void * __cdecl operator new ( size_t amount ) +{ + return allocmem( (Dword)amount ); +} + +void __cdecl operator delete ( void *pointer ) +{ + if ( pointer != NULL ) freemem( pointer ); +} + +void __cdecl operator delete [] ( void *pointer ) +{ + if ( pointer != NULL ) freemem( pointer ); +} + + +// +Dword mmMutex = FALSE; +MemBlock *rootfree = NULL; +MemBlock *rootuser = NULL; +bool mmInitialized = false; +Byte *mmHeapTop = NULL; + + +// +Byte * AllocMemFromSystem( Dword reqSize ) +{ + Byte *result; + sProcessInfo pInfo; + + // + if ( mmInitialized ) + { + result = mmHeapTop; + } + else + { + // + kos_ProcessInfo( &pInfo ); + // + result = (Byte *)(pInfo.processInfo.used_memory + 1); + // + mmInitialized = true; + } + // + if ( ! kos_ApplicationMemoryResize( ((Dword)result) + reqSize ) ) + { + result = NULL; + } + // + mmHeapTop = result + reqSize; + // + return result; +} + + +// +Byte *allocmem( Dword reqsize ) +{ + MemBlock *BlockForCheck; + MemBlock *LastKnownGood; + Dword tail; + Byte *address; + + //подровняем размер + if( ( tail = reqsize % SIZE_ALIGN ) != 0 ) + { + reqsize += SIZE_ALIGN - tail; + } + + LastKnownGood = NULL; + + // ждём освобождения мьютекса + while ( rtlInterlockedExchange( &mmMutex, TRUE ) ) + { + // + kos_Pause( 1 ); + } + + //ищем подходящий свободный блок + if( rootfree != NULL ) + { + for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next ) + { + if ( BlockForCheck->Size >= reqsize ) + { + //нашли + if ( LastKnownGood != NULL ) + { + if ( LastKnownGood->Size >= BlockForCheck->Size ) + LastKnownGood = BlockForCheck; + } + else + LastKnownGood = BlockForCheck; + if ( LastKnownGood->Size == reqsize ) + break; + } + if ( BlockForCheck->Next == NULL ) + break; + } + } + + if ( LastKnownGood != NULL ) + { + //проверим найденный блок на возможность деления + tail = LastKnownGood->Size - reqsize; + if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) ) + { + //будем разбивать + BlockForCheck = (MemBlock *)( ( (Byte *)LastKnownGood ) + tail ); + BlockForCheck->Size = reqsize; + //вставим занятый блок в начало списка занатых блоков + if( rootuser != NULL ) + { + BlockForCheck->Next = rootuser; + rootuser->Previous = BlockForCheck; + BlockForCheck->Previous = NULL; + rootuser = BlockForCheck; + } + else + { + rootuser = BlockForCheck; + BlockForCheck->Next = NULL; + BlockForCheck->Previous = NULL; + } + + //изменим размер оставшейся части + LastKnownGood->Size = tail - sizeof(MemBlock); + address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock); + + // отпустим мьютекс + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + else + { + //перемести блок из очереди свободных в начало очереди занятых + //сначала выкинем его из очереди свободных + if ( LastKnownGood->Previous != NULL ) + { + LastKnownGood->Previous->Next = LastKnownGood->Next; + } + else + { + //блок стоит в начале очереди + rootfree = LastKnownGood->Next; + } + if( LastKnownGood->Next != NULL ) + { + LastKnownGood->Next->Previous = LastKnownGood->Previous; + } + //теперь вставим его в очередь занятых + if( rootuser != NULL ) + { + LastKnownGood->Next = rootuser; + rootuser->Previous = LastKnownGood; + LastKnownGood->Previous = NULL; + rootuser = LastKnownGood; + } + else + { + rootuser = LastKnownGood; + LastKnownGood->Next = NULL; + LastKnownGood->Previous = NULL; + } + // + address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock); + + // отпустим мьютекс + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + } + else + { + //надо получить ещё кусочек памяти + LastKnownGood = (MemBlock *)AllocMemFromSystem( reqsize + sizeof(MemBlock) ); + // + if( LastKnownGood != NULL ) + { + LastKnownGood->Size = reqsize; + //теперь вставим его в очередь занятых + if( rootuser != NULL ) + { + LastKnownGood->Next = rootuser; + rootuser->Previous = LastKnownGood; + LastKnownGood->Previous = NULL; + rootuser = LastKnownGood; + } + else + { + rootuser = LastKnownGood; + LastKnownGood->Next = NULL; + LastKnownGood->Previous = NULL; + } + address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock); + + // отпустим мьютекс + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + } + + // отпустим мьютекс + rtlInterlockedExchange( &mmMutex, FALSE ); + + // + rtlDebugOutString( "allocmem failed." ); + kos_ExitApp(); + // + return NULL; +} + +// +Dword freemem( void *vaddress ) +{ + Dword result; + + Byte *checknext, *address = (Byte *)vaddress; + + // ждём освобождения мьютекса + while ( rtlInterlockedExchange( &mmMutex, TRUE ) ) + { + // + kos_Pause( 1 ); + } + + MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) ); + + result = released->Size; + + //убираем блок из списка занятых + if ( released->Previous != NULL ) + { + released->Previous->Next = released->Next; + } + else + { + rootuser = released->Next; + } + if ( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + //закинем теперь этот блок в список свободных + released->Next = rootfree; + released->Previous = NULL; + rootfree = released; + if ( released->Next != NULL ) + { + released->Next->Previous = released; + } + + //теперь поищем смежные свободные блоки + checknext = (Byte *)(rootfree) + ( rootfree->Size + sizeof(MemBlock) ); + // + for ( released = rootfree->Next; released != NULL; released = released->Next ) + { + if ( checknext == (Byte *)released ) + { + //собираем блоки вместе + //сначала выкинем из очереди свободных + released->Previous->Next = released->Next; + if( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + //теперь увеличим размер корневого блока + rootfree->Size += released->Size + sizeof(MemBlock); + break; + } + } + //если надо, поищем блоки перед текщим. + checknext = (Byte *)(rootfree); + // + if ( released == NULL ) + { + for ( released = rootfree->Next; released != NULL; released = released->Next ) + { + if ( checknext == (Byte *)released + ( released->Size + sizeof(MemBlock) ) ) + { + //собираем блоки вместе + //увеличим размер блока + released->Size += rootfree->Size + sizeof(MemBlock); + //теперь выкинем из очереди свободных + released->Previous->Next = released->Next; + if ( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + //и закинем его в начало очереди вместо присоединённого блока из корня списка + if ( rootfree->Next != NULL ) + { + rootfree->Next->Previous = released; + } + released->Next = rootfree->Next; + released->Previous = NULL; + rootfree = released; + break; + } + } + } + + // отпустим мьютекс + rtlInterlockedExchange( &mmMutex, FALSE ); + + return result; +} +