#define RGB_RESET 0x03C6
#define RGB_READ 0x03C7
#define RGB_WRITE 0x03C8
#define RGB_DATA 0x03C9
#include
#include
#include
#include
#include
#include
#include
#include
#include "svgautil.h"
#include "svgautil.c"
#include "svga256.h"
typedef struct tagBITMAPFILEHEADER
{
unsigned int bfType;
unsigned long bfSize;
unsigned int bfReserved1;
unsigned int bfReserved2;
unsigned long bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER
{
unsigned long biSize;
unsigned long biWidth;
unsigned long biHeight;
unsigned int biPlanes;
unsigned int biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
unsigned long biXPelsPerMeter;
unsigned long biYPelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD
{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} RGBQUAD;
FILE *ptr;
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
RGBQUAD rgbq[256];
char files[100][14];
int height;
void putPixel(int& i, int& j, char tmp2, int flag) // draws a pixel in
{ // correct color from
putpixel(j, i, tmp2 + 1 - flag); // color table at
j++; // desired location
if (j == (getmaxx() + bmih.biWidth) / 2) // on screen.
{
j = (getmaxx() - bmih.biWidth) / 2;
i--;
height++;
switch(bmih.biBitCount) // so that new line is aligned at long word boundary.
{
case 8 : if ((bmih.biWidth % 4) != 0) // for 8-bit BMP.
for (int k = 4; k > (bmih.biWidth % 4); k--)
getc(ptr);
break;
case 4 : if (((bmih.biWidth / 2) % 4) != 0) // for 4-bit BMP.
for (int k = 4; k > ((bmih.biWidth / 2) % 4); k--)
getc(ptr);
break;
}
}
}
void getDir(int& i) // gets the contents of a directory
{ // and stores them in the array 'files'.
struct ffblk ffblk;
int done;
for (done = 0; done < 100; done++) // initialising file array.
files[done][13] = ' ';
done = findfirst("*", &ffblk, FA_DIREC); // for getting sub-directories.
while (!done)
{
if (strcmp(ffblk.ff_name, ".") && !(ffblk.ff_fsize))
{
strcpy(files[i], ffblk.ff_name);
files[i][13] = '\\';
i++;
}
done = findnext(&ffblk);
}
done = findfirst("*.bmp", &ffblk, 0); // for .BMP files.
while (!done)
{
strcpy(files[i], ffblk.ff_name);
i++;
done = findnext(&ffblk);
}
}
void highlight() // highlights selected file or directory.
{
textbackground(YELLOW);
textcolor(BLUE);
}
void normal() // removes highlight.
{
textbackground(BLUE);
textcolor(YELLOW);
}
int huge DetectVGA256()
{
int Vid = 2;
return Vid;
}
void setPalette(int index, int red, int green, int blue)
{
outp(RGB_RESET, 0xFF); //Prepare the VGA card for the color change
outp(RGB_WRITE, index); //Tell which palette register to write to
outp(RGB_DATA, red); //change the red value
outp(RGB_DATA, green); //change the green value
outp(RGB_DATA, blue); //change the blue value
}
main()
{
FILE *p;
unsigned char tmp1, tmp2;
int i, j, k, flag, no_files; // flag checks if color table is of max. size.
char filename[14], ch;
char *path, drive[2], dir[100], file[10], ext[4];
path = searchpath("svga256.bgi");
fnsplit(path, drive, dir, file, ext);
getcwd(path, 100);
start :
_setcursortype(_NOCURSOR);
normal();
clrscr();
cprintf("ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\r\n");
cprintf(" BMPview Version 2.3 º Developed by Vineet Verma\r\n");
cprintf("ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ\r\n");
gotoxy(2, 22);
cprintf("ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ\r\n");
cprintf(" Esc - exit; Arrow keys - navigate; Enter - select file");
for (i = 2; i < 24; i++)
{
gotoxy(1, i);
if ((i == 22) || (i == 3)) putch('Ì');
else putch('º');
gotoxy(58, i);
if ((i == 22) || (i == 3)) putch('¹');
else putch('º');
gotoxy(79, i);
putch('º');
}
gotoxy(1, 24);
cprintf("ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ");
j = k = no_files = 0; // 'j' keeps track of which one is highlighted.
getDir(no_files); // 'k' keeps track of which one is at top of page.
window(60, 2, 78, 23);
do
{
clrscr();
for (i = 1; i < 23; i++)
{
if ((i + k) > no_files) break;
gotoxy(1, i);
if ((i + k - 1) == j) highlight();
if ((files[i - 1 + k][13] == '\\') && (strcmp(files[i - 1 + k], "..")))
cprintf("\\");
cprintf(files[i - 1 + k]);
normal();
}
switch(ch = getch())
{
case 72 : if (j) // UP arrow.
{
if (j == k)
{
j--;
k--;
}
else
j--;
}
break;
case 80 : if (j != (no_files - 1)) // DOWN arrow.
{
if (j == (k + 21))
{
j++;
k++;
}
else
j++;
}
break;
case 73 : if (k < 22) // Page Up.
{
k = 0;
if (j < 22) j = 0;
else j -= 22;
}
else
{
j -= 22;
k -= 22;
}
break;
case 81 : if ((no_files - j) < 23) // Page Down.
{
j = no_files - 1;
if ((no_files - k) > 21) k = no_files - 1;
}
else
{
j += 22;
k += 22;
}
break;
case 13 : if (files[j][13] == '\\') // Enter pressed.
{ // if directory selected,
chdir(files[j]); // change directory.
j = k = no_files = 0;
getDir(no_files);
break;
}
else
{ // if file selected,
strcpy(filename, files[j]); // exit loop to display
ch = 27; // image.
break;
}
break;
case 27 : window(1, 1, 80, 24); // Esc.
textbackground(BLACK);
textcolor(WHITE);
lowvideo();
_setcursortype(_NORMALCURSOR);
clrscr();
chdir(path);
exit(0);
break;
}
}
while (ch != 27);
// start reading the file.
window(1, 1, 80, 24);
normal();
gotoxy(1, 8);
ptr = fopen(filename, "rb");
flag = 0;
fread(&bmfh, sizeof(bmfh), 1, ptr); // read bitmap file header.
fread(&bmih, sizeof(bmih), 1, ptr); // read bitmap information header.
if (bmfh.bfType != 19778) // BMP signature.
{
cprintf("\r\nº %s is not a BMP file!", filename);
gotoxy(3, 23);
cprintf("Esc - exit program; Any other key - continue");
tmp1 = getch();
if (tmp1 == 27)
{
clrscr();
exit(0);
}
else
goto start;
}
cprintf("\r\nº Image information\r\n");
cprintf("º ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ\r\n\r\n");
cout << "º File size : " << bmfh.bfSize << " bytes.\n";
cout << "º Image size : " << bmih.biWidth << " X " << bmih.biHeight << " pixels.\n";
cout.setf(ios::fixed, ios::floatfield);
cout << "º Colors : " << pow(2, bmih.biBitCount) << " (" << bmih.biBitCount << " bits per pixel).\n";
if (bmih.biBitCount > 8)
{
cprintf("\r\nº Cannot read 24-bit BMP!");
gotoxy(3, 23);
cprintf("Esc - exit program; Any other key - continue ");
tmp1 = getch();
if (tmp1 == 27)
{
clrscr();
exit(0);
}
else
goto start;
}
cprintf("º Compression : ");
if (bmih.biCompression == 0) cprintf("None.\r\n\r\n");
else cprintf("Run Length Encoded.\r\n\r\n");
if (bmih.biClrUsed == 0) bmih.biClrUsed = pow(2, bmih.biBitCount);
if (bmih.biClrUsed > 254) flag = 1;
gotoxy(3, 23);
cprintf("Esc - Don't view; Enter - View; F2 - Save as grayscale");
while ((ch = getch()) != 13)
switch(ch)
{
case 27 : goto start; // (Esc) - refresh display since image is not to be displayed.
case 60 : fclose(ptr); // (F2) - replace color table
ptr = fopen(filename, "rb"); // of image by a grayscale
p = fopen("temp", "wb"); // color table to convert it
for (i = 0; i < 54; i++) // to grayscale. `temp' is a
putc(getc(ptr), p); // temporary file for conversion.
for (i = 0; i < bmih.biClrUsed; i++) // reading original image
{ // to extract rgb values
tmp1 = 0; // and getting grayscale
for (j = 0; j < 3; j++) // value (r+g+b)/3.
tmp1 += getc(ptr) / 3;
getc(ptr); // reserved byte.
for (j = 0; j < 3; j++) // writing grayscale value
putc(tmp1, p); // in color table of output file.
putc(0, p); // reserved byte.
}
while (!feof(ptr)) // copying rest of BMP
putc(getc(ptr), p); // to output file.
fclose(ptr);
fclose(p);
p = fopen("temp", "rb"); // writing data into file
ptr = fopen(filename, "wb"); // to complete conversion.
while (!feof(p))
putc(getc(p), ptr);
fclose(ptr);
fclose(p);
remove("temp");
ptr = fopen(filename, "rb"); // getting file into state
for (i = 0; i < 54; i++) // it was in before conversion
getc(ptr); // i.e. pointer is at start of
gotoxy(5, 18); // color table.
cprintf("Conversion complete.");
break;
}
rgbq[0].rgbRed = rgbq[0].rgbBlue = rgbq[0].rgbGreen = 0; // set first entry in palette to black for black background.
for (i = 1 - flag; i < bmih.biClrUsed + 1 - flag; i++) // storing the color table.
{
rgbq[i].rgbBlue = getc(ptr);
rgbq[i].rgbGreen = getc(ptr);
rgbq[i].rgbRed = getc(ptr);
tmp1 = getc(ptr);
}
for (i = bmih.biClrUsed + 1 - flag; i < 255 + flag; i++) // initialising unused entries.
rgbq[i].rgbRed = rgbq[i].rgbBlue = rgbq[i].rgbGreen = 0;
if (!flag) rgbq[255].rgbRed = rgbq[255].rgbBlue = rgbq[255].rgbGreen = 255; // set last entry in palette to white for white foreground.
int gd = DETECT, gm; // enter graphics mode to display image.
installuserdriver("Svga256", DetectVGA256);
initgraph(&gd, &gm, dir);
outtextxy(1, 1, "Please wait while image loads...");
for (i = 0; i < 256; i++)
setPalette(i, rgbq[i].rgbRed / 4, rgbq[i].rgbGreen / 4, rgbq[i].rgbBlue / 4);
clearviewport();
i = (getmaxy() + bmih.biHeight) / 2; // start display of image.
j = (getmaxx() - bmih.biWidth) / 2;
height = 0; // height keeps track of how many lines have been drawn.
while (!feof(ptr))
{
tmp1 = getc(ptr); // read character from file.
switch(bmih.biBitCount)
{
case 8 : if (height == bmih.biHeight) break;
if (bmih.biCompression == 1) // for 8-bit BMP.
{ // (RLE encoded).
tmp2 = getc(ptr);
if (tmp1 == 0)
{
switch(tmp2)
{
case 0 : i--; // end of line.
j = (getmaxx() - bmih.biWidth) / 2;
break;
case 1 : goto finish; // end of BMP.
break;
case 2 : j += getc(ptr); // offset of next pixel.
i -= getc(ptr);
break;
default : for (k = 0; k < tmp2; k++)
putPixel(i, j, getc(ptr), flag);
if ((tmp2 % 2) != 0) getc(ptr);
}
}
else
{
for (k = 0; k < tmp1; k++)
putPixel(i, j, tmp2, flag);
}
}
else // not encoded.
{
tmp2 = tmp1;
putPixel(i, j, tmp2, flag);
}
break;
case 4 : if (height == bmih.biHeight) break; // for 4-bit BMP.
tmp2 = tmp1 >> 4;
putPixel(i, j, tmp2, flag);
if (height == bmih.biHeight) break;
tmp2 = tmp1 << 4;
tmp2 >>= 4;
putPixel(i, j, tmp2, flag);
break;
case 1 : for (k = 0; k < 8; k++) // for 1-bit BMP.
{
if (height == bmih.biHeight) break; // if BMP ends in middle of byte.
tmp2 = tmp1 & 128;
tmp1 <<= 1;
if (tmp2 == 0) ;
else tmp2 = 1;
putPixel(i, j, tmp2, flag);
}
break;
}
}
finish :
fclose(ptr);
getch();
closegraph();
goto start;
}