#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; }