home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR2
/
DVPG30FS.ZIP
/
JVDRWFST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-05
|
22KB
|
732 lines
/*
* drawing routines for dvpeg
*
*/
#include "viewdef.h"
#include "extern.h"
#include <dos.h>
#include <conio.h>
#define new_vga /* new faster, vga routines */
unsigned char FAR * data_ptr; /* pointer to data array, used by all drawing routines */
unsigned char FAR * data_ref_ptr; /* always point to start of the data structure */
int row, /* row, col counters for plotting */
col,
x; /* counter */
unsigned char
red, green, blue; /* colors for saving full 24 bit resolution */
static JSAMPROW /* output_row, /* pseudo struct to hold 1 line for drawing */
ptr0, ptr1, ptr2; /* pointer to rows */
extern int xwidth;
/*
* variables used in drawing routines that are setup as global variables
*
* red_tint, green_tint, blue_tint, ===> red, green, blue tint controls
* color_scale ==> factor to scale pallete up or down
* contrast_scale ==> factor to scale contrast up or down 0 -> +/-32
*
* x_max, y_max ==> physical pixel size of the screen
* x_size, y_size ==> picture size in pixels
*
* maxx ==> width of one pixel row in pixels
* xwidth ==> width of one pixel row in bytes
*
* image_x_offset ==> offset (in pixels) of the x axis because the picture is smaller than the X axis size
*
*/
#if 0
void warning_beep(int tone1, int tone2)
{
sound(tone1);
delay(200);
sound(tone2);
delay(200);
sound(tone1);
delay(200);
nosound();
}
#endif
/*
* clear 1M of video memory in 64k blocks
* - assume that there is 1M of video memory
*/
void clear_video_memory(int num_banks)
{
int bank_number;
long int vid_addr = 0x0a0000000;
for (bank_number = 0; bank_number < num_banks; bank_number++){
_AX = bank_number;
newbank();
asm{
mov ax, 0x0
mov cx, 0x8000
les di, [vid_addr]
rep stosw
}
/* _fmemset((void FAR *) MK_FP(0xA000, 0), 0, (size_t)0xffff);
this was using int 21 AH=40 for some reason
*/
}
}
/* raw string copy to video memory but watch out for bank crossings
*
* video_mem is the address (in the 1M bank) to start at calculated by gr_col and gr_row the row and column address
* width is the amount of memory (bytes) to copy
*/
void video_copy(int gr_row, unsigned char FAR * data_row)
{
unsigned int difference;
unsigned long video_mem;
unsigned int x_offset;
x_offset = image_x_offset * bytes_per_pixel;
video_mem = (unsigned long) gr_row * maxx + x_offset;
/* set memory bank */
_AX = video_mem >> 16;
newbank();
/* basic size test to see if it is only one line
* also account for offset in the drawing if the image is centered
*/
/* if ((visable_bytes_per_line + x_offset) > maxx) width = maxx - x_offset;*/
/* need to check memory bank crossing */
if ((unsigned long) (video_mem & 0x0ffff) + visable_bytes_per_line > 0xffff){
difference = (0xffff - (unsigned int) video_mem) + 1;
_fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) difference);
_AX = (video_mem >> 16) + 1;
newbank();
_fmemcpy((void FAR *) MK_FP(video_mem_seg, 0), data_row + difference, (size_t) visable_bytes_per_line - difference);
}
else
_fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) visable_bytes_per_line);
}
#ifdef new_vga
/*
* line copy for the pecularities of the VGA screen
*
* do all 4 banks in parallel
* assume that each component is equally spaced in a line ie each component
* is seperated by maxx >> 2
*/
void VGA_video_copy(int gr_row, unsigned char FAR * data_row)
{
unsigned long video_mem;
unsigned int x_offset;
int vis_bytes_line;
vis_bytes_line = (visable_bytes_per_line + 7) >> 3; /* VGA is 1/8 size */
/*if (visable_bytes_per_line & 0x07) vis_bytes_line++;*/
x_offset = (image_x_offset * bytes_per_pixel) >> 3;
video_mem = (unsigned long) gr_row * maxx + x_offset;
/* set memory bank */
_AX = video_mem >> 16;
newbank();
/* everything will be in one memory bank since there are no page crossings in a line */
outpw(0x03c4, 2 | (1 << 8)); /* VGA plane 0 */
_fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) vis_bytes_line);
data_row += maxx;
outpw(0x03c4, 2 | (2 << 8)); /* VGA plane 1 */
_fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) vis_bytes_line);
data_row += maxx;
outpw(0x03c4, 2 | (4 << 8)); /* VGA plane 2 */
_fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) vis_bytes_line);
data_row += maxx;
outpw(0x03c4, 2 | (8 << 8)); /* VGA plane 3 */
_fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) vis_bytes_line);
}
#endif
/*
* this routine corrects for incorrect saving of Targa (bottom up) or
* interlaced GIF images by mapping the input to the convoluted numbering
*/
int fix_order(int image_row)
{
unsigned int temp1, temp2, temp3, i, outp;
switch(row_ordering){
case INTERLACED:
return image_row;
/* temp1 = picture_y_size >> 1;
temp2 = picture_y_size >> 2;
temp3 = picture_y_size >> 3;
for (i=0; i < picture_y_size; i++){
if (i < temp3)
outp = i << 3;
else
if (i < temp2)
outp = ((i - temp3) << 3) + 4;
else
if (i < temp1)
outp = ((i - temp2) << 2) + 2;
else
outp = ((i - temp1) << 1) + 1;
if (outp == image_row) break;
}
return i;*/
case UPSIDE_DOWN:
return picture_y_size - image_row - 1;
case NORMAL:
return image_row;
}
}
/*
* This function is called repeatedly, with a few more rows of pixels supplied
* on each call. With the current JPEG code, some multiple of 8 rows will be
* passed on each call except the last, but it is extremely bad form to depend
* on this. You CAN assume num_rows > 0.
* The data is supplied in top-to-bottom row order (the standard order within
* a JPEG file). If you cannot readily use the data in that order, you'll
* need an intermediate array to hold the image. See jwrrle.c for an example
* of outputting data in bottom-to-top order.
*
* The data is supplied as a 3-D array of JSAMPLEs, indexed as
* JSAMPLE pixel_data[component][row][column]
* where component runs from 0 to cinfo->final_out_comps-1, row runs from 0 to
* num_rows-1, and column runs from 0 to cinfo->image_width-1 (column 0 is
* left edge of image). Note that this is actually an array of pointers to
* pointers to arrays rather than a true 3D array, since C does not support
* variable-size multidimensional arrays.
* JSAMPLE is typically typedef'd as "unsigned char". If you want your code
* to be as portable as the JPEG code proper, you should always access JSAMPLE
* values with the GETJSAMPLE() macro, which will do the right thing if the
* machine has only signed chars.
*
* If quantize_colors is true, then there is only one component, and its values
* are indexes into the previously supplied colormap. Otherwise the values
* are actual data in your selected output colorspace.
*/
/*
* this is a do-nothing routine to provide a safe return from a call to put pixel routines
*/
void put_pixel_not (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
{
}
/*
* draw 1 line on the screen as pointed to by the data struct
* given row # of the image (top = 0 ...) and the pointer to 1/2/3 bytes
*
* for 8/15/16 bit modes
*
* does not handle interlaced images or bottom up (must be done outside)
* but lines are accepted in any order
*/
void draw_line(int image_row, unsigned char FAR * data_ptr, unsigned char FAR * buffer_ptr)
{
unsigned char FAR * data_pointer;
unsigned char FAR * formed_data_ptr;
unsigned int FAR * formed_data_int_ptr;
unsigned int FAR * data_int_ptr;
int row_inc; /* row increment in the data struct */
int zoom_row;
int drawing_row; /* row counter for drawing - has the offset for y axis centering */
int h_shrink; /* horizontal zoom counter */
int data, data1, data2, data3, data4, bit_loc; /* VGA temp storage for line generation */
if (image_row % shrink != 0) return; /* only draw row if required */
#if 0
if (image_row >= picture_y_max){
warning_beep(400, 600);
return;
}
if (image_row < picture_y_offset){
warning_beep(1200, 1600);
return;
}
#else
if (image_row >= picture_y_max) return;
if (image_row < picture_y_offset) return;
#endif
formed_data_ptr = buffer_ptr;
formed_data_int_ptr = (unsigned int FAR *) buffer_ptr;
row_inc = shrink * bytes_per_pixel;
h_shrink = zoom_inc;
drawing_row = (image_row - picture_y_offset) / shrink * (5 - zoom_inc) + image_y_offset;
data_pointer = data_ptr + (picture_x_offset * bytes_per_pixel);
data_int_ptr = (unsigned int FAR *) data_pointer;
if (zoom_inc == 4 && shrink == 1 && video_resolution != VGA)
video_copy(drawing_row, data_pointer);
else
switch(video_resolution){
case VGA:
#ifdef new_vga /* use this for VGA */
#if 0
/* the only way to really really speed this up is to pack the bits into
* the data storage
* But this does not allow for easy zooming since you have to unpack the
* data and then selectively re-insert
*/
if (zoom_inc == 4){ /* use this for shrink, non-shrunk but NOT ZOOMED */
data1 = data2 = data3 = data4 = 0;
bit_loc = 7;
data_pointer = data_ptr + (picture_x_offset * bytes_per_pixel);
for (x = image_x_offset; x < image_x_max ; x++){
data = remap[0][*data_pointer];
data_pointer += row_inc;
data1 |= ((data & 0x01) << bit_loc);
data2 |= (((data & 0x02) >> 1) << bit_loc);
data3 |= (((data & 0x04) >> 2) << bit_loc);
data4 |= (((data & 0x08) >> 3) << bit_loc);
if (--bit_loc < 0){
bit_loc = 7;
*formed_data_ptr = (unsigned char) data1;
formed_data_ptr[maxx] = (unsigned char) data2;
formed_data_ptr[maxx << 1] = (unsigned char) data3;
formed_data_ptr[maxx + (maxx << 1)] = (unsigned char) data4;
formed_data_ptr++;
data1 = data2 = data3 = data4 = 0;
}
}
if (bit_loc < 7){ /* dump out last 1 .. 7 pixels */
*formed_data_ptr = (unsigned char) data1;
formed_data_ptr[maxx] = (unsigned char) data2;
formed_data_ptr[maxx << 1] = (unsigned char) data3;
formed_data_ptr[maxx + (maxx << 1)] = (unsigned char) data4;
}
}
else{
#endif
data1 = data2 = data3 = data4 = 0;
bit_loc = 7;
data_pointer = data_ptr + (picture_x_offset * bytes_per_pixel);
data = remap[0][*data_pointer];
for (x = image_x_offset; x < image_x_max ; x++){
data1 |= ((data & 0x01) << bit_loc);
data2 |= (((data & 0x02) >> 1) << bit_loc);
data3 |= (((data & 0x04) >> 2) << bit_loc);
data4 |= (((data & 0x08) >> 3) << bit_loc);
if (--bit_loc < 0){
bit_loc = 7;
*formed_data_ptr = (unsigned char) data1;
formed_data_ptr[maxx] = (unsigned char) data2;
formed_data_ptr[maxx << 1] = (unsigned char) data3;
formed_data_ptr[maxx + (maxx << 1)] = (unsigned char) data4;
formed_data_ptr++;
data1 = data2 = data3 = data4 = 0;
}
if ((h_shrink & 0xFC) != 0){
h_shrink = zoom_inc;
data_pointer += row_inc;
data = remap[0][*data_pointer];
}
else
h_shrink++;
}
if (bit_loc < 7){ /* dump out last 1 .. 7 pixels */
*formed_data_ptr = (unsigned char) data1;
formed_data_ptr[maxx] = (unsigned char) data2;
formed_data_ptr[maxx << 1] = (unsigned char) data3;
formed_data_ptr[maxx + (maxx << 1)] = (unsigned char) data4;
}
#if 0
}
#endif
for (zoom_row = zoom_inc; zoom_row <= 4; zoom_row++)
VGA_video_copy(drawing_row++, buffer_ptr);
#else
for (zoom_row = zoom_inc; zoom_row <= 4; zoom_row++){
data_pointer = data_ptr + (picture_x_offset * bytes_per_pixel);
for (x = image_x_offset; x < image_x_max ; x++){
put16Pixel(x, drawing_row, remap[0][*data_pointer]);
if ((h_shrink & 0xFC) != 0){
data_pointer += row_inc;
h_shrink = zoom_inc;
}
else
h_shrink++;
}
drawing_row++;
}
#endif
break;
case SVGA:
for (x = image_x_offset; x < image_x_max ; x++){
*formed_data_ptr++ = *data_pointer;
if ((h_shrink & 0xFC) != 0){
data_pointer += row_inc;
h_shrink = zoom_inc;
}
else
h_shrink++;
}
for (zoom_row = zoom_inc; zoom_row <= 4; zoom_row++)
video_copy(drawing_row++, buffer_ptr);
break;
#ifndef small_viewer
case SVGA_15_bit:
case SVGA_16_bit:
for (x = image_x_offset; x < image_x_max ; x++){
*formed_data_int_ptr++ = *data_int_ptr;
if ((h_shrink & 0xFC) != 0){
data_int_ptr += shrink;
h_shrink = zoom_inc;
}
else
h_shrink++;
}
for (zoom_row = zoom_inc; zoom_row <= 4; zoom_row++)
video_copy(drawing_row++, buffer_ptr);
break;
case SVGA_24_bit:
for (x = image_x_offset; x < image_x_max ; x++){
*formed_data_ptr++ = *data_pointer;
*formed_data_ptr++ = *(data_pointer + 1);
*formed_data_ptr++ = *(data_pointer + 2);
if ((h_shrink & 0xFC) != 0){
data_pointer += row_inc;
h_shrink = zoom_inc;
}
else
h_shrink++;
}
for (zoom_row = zoom_inc; zoom_row <= 4; zoom_row++)
video_copy(drawing_row++, buffer_ptr);
#endif
}
}
/*
* Write some rows of output data - 16 & 256 color modes only
*
* note ------ row is not going from 0 to max because it goes in sections ------
* so gr_row is set externally and incremented here - this allows external control
* ie in the case of interlaced gifs - dito for read_row
*/
void put_pixel_rows (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
{
for (row = 0; row < num_rows; row++){
data_ptr = pixel_data[0][row];
if (enable_pan){
data_ref_ptr = *((*cinfo->emethods->access_big_sarray) (raw_pic_ptr, read_row++, TRUE));
_fmemcpy((void FAR *) data_ref_ptr, (void FAR *) data_ptr, (size_t) bytes_per_line);
}
draw_line(gr_row++, data_ptr, line_buffer_ptr);
}
}
/*
* pan the 4/8/15/16/24 image from the buffer
* no tint controls unless done thru pallet for 4/8 bit modes
*/
void pan_image(decompress_info_ptr cinfo) /* pan the image from buffer -> screen */
{
int actual_row, row;
for (row = picture_y_offset; row < picture_y_max; row++){
actual_row = fix_order(row);
data_ptr = *((*cinfo->emethods->access_big_sarray) (raw_pic_ptr, actual_row, FALSE));
draw_line(row, data_ptr, line_buffer_ptr);
if (allow_video_exit && kbhit()) return;
}
}
#ifndef small_viewer /* only include this in the full blown version */
/*
* put pixel routine for 15/16/24 bit video modes
*
* this is not designed for speed, JPEGs use a different routine
* note ------ row is not going from 0 to max because it goes in sections ------
*/
void put_hi_pixel (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
{
unsigned int FAR * int_data_ptr;
for (row = 0; row < num_rows; row++) {
ptr0 = pixel_data[0][row];
ptr1 = pixel_data[1][row];
ptr2 = pixel_data[2][row];
if (!enable_pan)
read_row = 0;
data_ptr = data_ref_ptr = *((*cinfo->emethods->access_big_sarray) (raw_pic_ptr, read_row++, TRUE));
int_data_ptr = (unsigned int FAR *) data_ptr;
for (col = 0; col < picture_x_size; col++){
RGB_read_and_tint();
/* 16 bit red color range is wrong, all red but shading is not right */
/* blue looks good ie red != 0*/
/* 16 bit green intensity range is wrong - no red tint visable */
switch (video_resolution){
case SVGA_15_bit:
*int_data_ptr = (unsigned int)(red >> 3) + ((green << 2) & 0x3e0) + ((blue << 7) & 0x7c00);
int_data_ptr++;
break;
case SVGA_16_bit:
/* *int_data_ptr = (unsigned int)(red >> 3) + ((green << 2) & 0x3e0) + ((blue << 7) & 0x7c00);*/
*int_data_ptr = ((unsigned int)red >> 3) + ((unsigned int)(green << 3) & 0x7e0) + (((unsigned int)blue << 8) & 0xf800);
int_data_ptr++;
break;
case SVGA_24_bit:
*data_ptr++ = red;
*data_ptr++ = green;
*data_ptr++ = blue;
}
}
}
draw_line(gr_row++, data_ref_ptr, line_buffer_ptr);
}
/*
* tint the 15 bit image by playing with the video memory directly
* No exiting because this can only be reversed if done totally
*/
void tint_15_image()
{
unsigned long offset, line_offset;
unsigned int data;
int bank;
int red, green, blue; /* colors for saving full 24 bit resolution */
bank = -1; /* make sure bank != offset >> 16 */
line_offset = (unsigned long)image_x_offset * bytes_per_pixel + (unsigned long)image_y_offset * (unsigned int)xwidth;
for (row = image_y_offset; row < image_y_max; row++){
offset = line_offset;
for (col = image_x_offset; col < image_x_max; col++){
/* do a bank check */
if ((offset >> 16) != bank){ /* ie since always start at 0 and count by 2 ... */
bank = offset >> 16;
_AX = bank;
newbank();
}
data = peek(video_mem_seg, (unsigned int) offset);
red = (unsigned int) (data & 0x1f); /* convert from 5 bits to 8 */
red += (signed char) tint_table[0][red];
green = (unsigned int) (data & 0x3e0) >> 2;
green += (signed char) tint_table[1][green];
blue = (unsigned int) (data & 0x7c00) >> 7;
blue += (signed char) tint_table[2][blue];
if (((red & 0xffe0) | (green | blue) & 0xff00) == 0){
/* if (red < 32 && green < 256 && blue < 256 && red >= 0 && green >= 0 && blue >= 0){*/
poke(video_mem_seg, offset, red | ((green << 2) & 0x3e0) + ((blue << 7) & 0x7c00));
}
offset += 2;
}
line_offset += maxx;
}
}
/*
* tint the 16 bit image by playing with the video memory directly
* No exiting because this can only be reversed if done totally
*/
void tint_16_image()
{
unsigned long offset, line_offset;
unsigned int data;
int bank;
int red, green, blue; /* colors for saving full 24 bit resolution */
bank = -1; /* make sure bank != offset >> 16 */
line_offset = (unsigned long)image_x_offset * bytes_per_pixel + (unsigned long)image_y_offset * (unsigned int)xwidth;
for (row = image_y_offset; row < image_y_max; row++){
offset = line_offset;
for (col = image_x_offset; col < image_x_max; col++){
/* do a bank check */
if ((offset >> 16) != bank){ /* ie since always start at 0 and count by 2 ... */
bank = offset >> 16;
_AX = bank;
newbank();
}
data = peek(video_mem_seg, (unsigned int) offset);
red = (unsigned int) (data & 0x1f); /* convert from 5 bits to 8 */
red += (signed char) tint_table[0][red];
green = (unsigned int) (data & 0x7e0) >> 3;
green += (signed char) tint_table[1][green];
blue = (unsigned int) (data & 0xf800) >> 8;
blue += (signed char) tint_table[2][blue];
if (red < 32 && green < 256 && blue < 256 && red >= 0 && green >= 0 && blue >= 0){
poke(video_mem_seg, offset, red | ((green << 3) & 0x7e0) + ((blue << 8) & 0xf800));
}
offset += 2;
}
line_offset += maxx;
}
}
/*
* tint the 24 bit image
* do by processing video memory directly
* - if a byte tripplet crosses a 64k boundary that pixel is not processed !
*/
void tint_24_image(void)
{
/* offset is the byte offset into the video memory,
* line_offset is the offset at the start of the line,
* this is necessary because some cards use a line width of 1920 bytes while others use 2048
* No exiting because this can only be reversed if done totally
*/
unsigned long offset, line_offset;
unsigned int data;
int bank;
int red, green, blue; /* colors for saving full 24 bit resolution */
line_offset = (unsigned long)image_x_offset * bytes_per_pixel + (unsigned long)image_y_offset * (unsigned int)xwidth;
bank = -1; /* make sure bank != offset >> 16 */
for (row = image_y_offset; row < image_y_max; row++){
offset = line_offset;
for (col = image_x_offset; col < image_x_max; col++){
/* do a bank check */
if ((offset >> 16) != bank){
bank = offset >> 16;
_AX = bank;
newbank();
}
if ( ((offset + 3) >> 16) == (offset >> 16) ){ /* ie if this all happens in the same bank */
red = (unsigned char) peekb(video_mem_seg, (unsigned int) offset);
red += (signed char) tint_table[0][red];
green = (unsigned char) peekb(video_mem_seg + 1, (unsigned int) offset);
green += (signed char) tint_table[1][green];
blue = (unsigned char) peekb(video_mem_seg + 2, (unsigned int) offset);
blue += (signed char) tint_table[2][blue];
if (red < 256 && red >= 0 && green < 256 && green >= 0 && blue < 256 && blue >= 0){
pokeb(video_mem_seg, offset, red);
pokeb(video_mem_seg + 1, offset, green);
pokeb(video_mem_seg + 2, offset, blue);
}
}
offset += bytes_per_pixel;
}
line_offset += maxx;
}
}
/*
* tint R, G, B seperate data streams into the red, green, blue vars
* do limiting to prevent color wraparound
* - this is used by any routine which reads the 3 * byte non-quantized data
*/
void near RGB_read_and_tint(void)
{
int red_new, green_new, blue_new;
red = GETJSAMPLE(*ptr2++);
green = GETJSAMPLE(*ptr1++);
blue = GETJSAMPLE(*ptr0++);
if (tint_loaded) return; /* shortcut if there is nothing to do */
red_new = new_tint(red, tint_factor_red) + red;
green_new = new_tint(green, tint_factor_green) + green;
blue_new = new_tint(blue, tint_factor_blue) + blue;
if (red_new < 256 && green_new < 256 && blue_new < 256 && red_new >= 0 && green_new >= 0 && blue_new >= 0){
red = red_new;
green = green_new;
blue = blue_new;
}
}
#else /* if small_viewer */
void put_hi_pixel (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
{}
void tint_15_image()
{}
void tint_16_image()
{}
void tint_24_image(void)
{}
#endif