home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR2 / DVPG30FS.ZIP / JVDRWFST.C < prev    next >
C/C++ Source or Header  |  1993-12-05  |  22KB  |  732 lines

  1. /*
  2.  *  drawing routines for dvpeg
  3.  *
  4.  */
  5.  
  6. #include "viewdef.h"
  7. #include "extern.h"
  8. #include <dos.h>
  9. #include <conio.h>
  10.  
  11. #define new_vga        /* new faster, vga routines */
  12.  
  13. unsigned char FAR * data_ptr;        /* pointer to data array, used by all drawing routines */
  14. unsigned char FAR * data_ref_ptr;        /* always point to start of the data structure */
  15.  
  16. int row,                /* row, col counters for plotting */
  17.     col,
  18.     x;                    /* counter */
  19.  
  20. unsigned char
  21.     red, green, blue;        /* colors for saving full 24 bit resolution */
  22.  
  23. static JSAMPROW  /* output_row,            /* pseudo struct to hold 1 line for drawing */
  24.             ptr0, ptr1, ptr2;        /* pointer to rows */
  25.  
  26. extern int xwidth;
  27.  
  28.  
  29. /*
  30.  * variables used in drawing routines that are setup as global variables
  31.  *
  32.  * red_tint, green_tint, blue_tint,    ===> red, green, blue tint controls
  33.  *    color_scale            ==> factor to scale pallete up or down
  34.  *    contrast_scale        ==> factor to scale contrast up or down  0 -> +/-32
  35.  *
  36.  * x_max, y_max        ==> physical pixel size of the screen
  37.  * x_size, y_size        ==> picture size in pixels
  38.  *
  39.  * maxx              ==> width of one pixel row in pixels
  40.  * xwidth                ==> width of one pixel row in bytes
  41.  *
  42.  * image_x_offset        ==> offset (in pixels) of the x axis because the picture is smaller than the X axis size
  43.  *
  44.  */
  45.  
  46. #if 0
  47. void warning_beep(int tone1, int tone2)
  48. {
  49. sound(tone1);
  50. delay(200);
  51. sound(tone2);
  52. delay(200);
  53. sound(tone1);
  54. delay(200);
  55. nosound();
  56. }
  57.  
  58. #endif
  59.  
  60.  
  61. /*
  62.  * clear 1M of video memory in 64k blocks
  63.  * - assume that there is 1M of video memory
  64.  */
  65.  
  66. void clear_video_memory(int num_banks)
  67. {
  68. int bank_number;
  69. long int vid_addr = 0x0a0000000;
  70.  
  71. for (bank_number = 0; bank_number < num_banks; bank_number++){
  72.     _AX = bank_number;
  73.     newbank();
  74.     asm{
  75.     mov ax, 0x0
  76.     mov cx, 0x8000
  77.     les di, [vid_addr]
  78.     rep stosw
  79.     }
  80. /*    _fmemset((void FAR *) MK_FP(0xA000, 0), 0, (size_t)0xffff);
  81.         this was using int 21 AH=40 for some reason
  82.         */
  83.     }
  84. }
  85.  
  86.  
  87.  
  88.  
  89. /* raw string copy to video memory but watch out for bank crossings
  90.  *
  91.  * video_mem is the address (in the 1M bank) to start at calculated by gr_col and gr_row the row and column address
  92.  * width is the amount of memory (bytes) to copy
  93.  */
  94.  
  95. void video_copy(int gr_row, unsigned char FAR * data_row)
  96. {
  97. unsigned int difference;
  98. unsigned long video_mem;
  99. unsigned int x_offset;
  100.  
  101. x_offset = image_x_offset * bytes_per_pixel;
  102.     video_mem = (unsigned long) gr_row * maxx + x_offset;
  103.  
  104. /* set memory bank */
  105.     _AX = video_mem >> 16;
  106.     newbank();
  107.  
  108. /* basic size test to see if it is only one line
  109.  *  also account for offset in the drawing if the image is centered
  110.  */
  111. /*    if ((visable_bytes_per_line + x_offset) > maxx) width = maxx - x_offset;*/
  112.  
  113. /* need to check memory bank crossing */
  114.     if ((unsigned long) (video_mem & 0x0ffff) + visable_bytes_per_line > 0xffff){
  115.         difference = (0xffff - (unsigned int) video_mem) + 1;
  116.         _fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) difference);
  117.         _AX = (video_mem >> 16) + 1;
  118.         newbank();
  119.         _fmemcpy((void FAR *) MK_FP(video_mem_seg, 0), data_row + difference, (size_t) visable_bytes_per_line - difference);
  120.         }
  121.     else
  122.         _fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) visable_bytes_per_line);
  123. }
  124.  
  125.  
  126.  
  127.  
  128. #ifdef new_vga
  129.  
  130. /*
  131.  * line copy for the pecularities of the VGA screen
  132.  *
  133.  * do all 4 banks in parallel
  134.  * assume that each component is equally spaced in a line ie each component
  135.  *  is seperated by maxx >> 2
  136.  */
  137.  
  138. void VGA_video_copy(int gr_row, unsigned char FAR * data_row)
  139. {
  140. unsigned long video_mem;
  141. unsigned int x_offset;
  142. int vis_bytes_line;
  143.  
  144. vis_bytes_line = (visable_bytes_per_line + 7) >> 3;        /* VGA is 1/8 size */
  145. /*if (visable_bytes_per_line & 0x07) vis_bytes_line++;*/
  146.  
  147. x_offset = (image_x_offset * bytes_per_pixel) >> 3;
  148. video_mem = (unsigned long) gr_row * maxx + x_offset;
  149.  
  150. /* set memory bank */
  151.     _AX = video_mem >> 16;
  152.     newbank();
  153.  
  154. /* everything will be in one memory bank since there are no page crossings in a line */
  155.  
  156. outpw(0x03c4, 2 | (1 << 8));        /* VGA plane 0 */
  157. _fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) vis_bytes_line);
  158. data_row += maxx;
  159.  
  160. outpw(0x03c4, 2 | (2 << 8));        /* VGA plane 1 */
  161. _fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) vis_bytes_line);
  162. data_row += maxx;
  163.  
  164. outpw(0x03c4, 2 | (4 << 8));        /* VGA plane 2 */
  165. _fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) vis_bytes_line);
  166. data_row += maxx;
  167.  
  168. outpw(0x03c4, 2 | (8 << 8));        /* VGA plane 3 */
  169. _fmemcpy((void FAR *) MK_FP(video_mem_seg, (unsigned) video_mem), (void FAR *) data_row, (size_t) vis_bytes_line);
  170. }
  171.  
  172. #endif
  173.  
  174.  
  175.  
  176.  
  177. /*
  178.  * this routine corrects for incorrect saving of Targa (bottom up) or
  179.  * interlaced GIF images by mapping the input to the convoluted numbering
  180.  */
  181.  
  182. int fix_order(int image_row)
  183. {
  184. unsigned int temp1, temp2, temp3, i, outp;
  185.  
  186. switch(row_ordering){
  187.     case INTERLACED:
  188.         return image_row;
  189. /*        temp1 = picture_y_size >> 1;
  190.         temp2 = picture_y_size >> 2;
  191.         temp3 = picture_y_size >> 3;
  192.         for (i=0; i < picture_y_size; i++){
  193.             if (i < temp3)
  194.                 outp = i << 3;
  195.             else
  196.             if (i < temp2)
  197.                 outp = ((i - temp3) << 3) + 4;
  198.             else
  199.             if (i < temp1)
  200.                 outp = ((i - temp2) << 2) + 2;
  201.             else
  202.                 outp = ((i - temp1) << 1) + 1;
  203.             if (outp == image_row) break;
  204.             }
  205.         return i;*/
  206.     case UPSIDE_DOWN:
  207.         return picture_y_size - image_row - 1;
  208.     case NORMAL:
  209.         return image_row;
  210.     }
  211. }
  212.  
  213. /*
  214.  * This function is called repeatedly, with a few more rows of pixels supplied
  215.  * on each call.  With the current JPEG code, some multiple of 8 rows will be
  216.  * passed on each call except the last, but it is extremely bad form to depend
  217.  * on this.  You CAN assume num_rows > 0.
  218.  * The data is supplied in top-to-bottom row order (the standard order within
  219.  * a JPEG file).  If you cannot readily use the data in that order, you'll
  220.  * need an intermediate array to hold the image.  See jwrrle.c for an example
  221.  * of outputting data in bottom-to-top order.
  222.  *
  223.  * The data is supplied as a 3-D array of JSAMPLEs, indexed as
  224.  *        JSAMPLE pixel_data[component][row][column]
  225.  * where component runs from 0 to cinfo->final_out_comps-1, row runs from 0 to
  226.  * num_rows-1, and column runs from 0 to cinfo->image_width-1 (column 0 is
  227.  * left edge of image).  Note that this is actually an array of pointers to
  228.  * pointers to arrays rather than a true 3D array, since C does not support
  229.  * variable-size multidimensional arrays.
  230.  * JSAMPLE is typically typedef'd as "unsigned char".  If you want your code
  231.  * to be as portable as the JPEG code proper, you should always access JSAMPLE
  232.  * values with the GETJSAMPLE() macro, which will do the right thing if the
  233.  * machine has only signed chars.
  234.  *
  235.  * If quantize_colors is true, then there is only one component, and its values
  236.  * are indexes into the previously supplied colormap.  Otherwise the values
  237.  * are actual data in your selected output colorspace.
  238.  */
  239.  
  240.  
  241.  
  242. /*
  243.  * this is a do-nothing routine to provide a safe return from a call to put pixel routines
  244.  */
  245. void put_pixel_not (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
  246. {
  247. }
  248.  
  249.  
  250.  
  251. /*
  252.  * draw 1 line on the screen as pointed to by the data struct
  253.  * given row # of the image (top = 0 ...) and the pointer to 1/2/3 bytes
  254.  *
  255.  *          for 8/15/16 bit modes
  256.  *
  257.  * does not handle interlaced images or bottom up (must be done outside)
  258.  * but lines are accepted in any order
  259.  */
  260.  
  261. void draw_line(int image_row, unsigned char FAR * data_ptr, unsigned char FAR * buffer_ptr)
  262. {
  263. unsigned char FAR * data_pointer;
  264. unsigned char FAR * formed_data_ptr;
  265. unsigned int FAR * formed_data_int_ptr;
  266. unsigned int FAR * data_int_ptr;
  267.  
  268. int row_inc;        /* row increment in the data struct */
  269. int zoom_row;
  270. int drawing_row;    /* row counter for drawing - has the offset for y axis centering */
  271. int h_shrink;        /* horizontal zoom counter */
  272. int data, data1, data2, data3, data4, bit_loc;        /* VGA temp storage for line generation */
  273.  
  274. if (image_row % shrink != 0) return;        /* only draw row if required */
  275. #if 0
  276. if (image_row >= picture_y_max){
  277.     warning_beep(400, 600);
  278.     return;
  279.     }
  280. if (image_row < picture_y_offset){
  281.     warning_beep(1200, 1600);
  282.     return;
  283.     }
  284. #else
  285. if (image_row >= picture_y_max) return;
  286. if (image_row < picture_y_offset) return;
  287. #endif
  288.  
  289. formed_data_ptr = buffer_ptr;
  290. formed_data_int_ptr = (unsigned int FAR *) buffer_ptr;
  291.  
  292. row_inc = shrink * bytes_per_pixel;
  293. h_shrink = zoom_inc;
  294. drawing_row = (image_row - picture_y_offset) / shrink * (5 - zoom_inc) + image_y_offset;
  295.  
  296. data_pointer = data_ptr + (picture_x_offset * bytes_per_pixel);
  297. data_int_ptr = (unsigned int FAR *) data_pointer;
  298.  
  299. if (zoom_inc == 4 && shrink == 1 && video_resolution != VGA)
  300.     video_copy(drawing_row, data_pointer);
  301. else
  302.     switch(video_resolution){
  303.     case VGA:
  304. #ifdef new_vga            /* use this for VGA */
  305. #if 0
  306. /* the only way to really really speed this up is to pack the bits into
  307.  * the data storage
  308.  * But this does not allow for easy zooming since you have to unpack the
  309.  *  data and then selectively re-insert
  310.  */
  311.         if (zoom_inc == 4){        /* use this for shrink, non-shrunk but NOT ZOOMED */
  312.             data1 = data2 = data3 = data4 = 0;
  313.             bit_loc = 7;
  314.             data_pointer = data_ptr + (picture_x_offset * bytes_per_pixel);
  315.             for (x = image_x_offset; x < image_x_max ; x++){
  316.                 data = remap[0][*data_pointer];
  317.                 data_pointer += row_inc;
  318.                 data1 |= ((data & 0x01) << bit_loc);
  319.                 data2 |= (((data & 0x02) >> 1) << bit_loc);
  320.                 data3 |= (((data & 0x04) >> 2) << bit_loc);
  321.                 data4 |= (((data & 0x08) >> 3) << bit_loc);
  322.                 if (--bit_loc < 0){
  323.                     bit_loc = 7;
  324.                     *formed_data_ptr = (unsigned char) data1;
  325.                     formed_data_ptr[maxx] = (unsigned char) data2;
  326.                     formed_data_ptr[maxx << 1] = (unsigned char) data3;
  327.                     formed_data_ptr[maxx + (maxx << 1)] = (unsigned char) data4;
  328.                     formed_data_ptr++;
  329.                     data1 = data2 = data3 = data4 = 0;
  330.                     }
  331.                 }
  332.             if (bit_loc < 7){        /* dump out last 1 .. 7 pixels */
  333.                 *formed_data_ptr = (unsigned char) data1;
  334.                 formed_data_ptr[maxx] = (unsigned char) data2;
  335.                 formed_data_ptr[maxx << 1] = (unsigned char) data3;
  336.                 formed_data_ptr[maxx + (maxx << 1)] = (unsigned char) data4;
  337.                 }
  338.             }
  339.         else{
  340. #endif
  341.             data1 = data2 = data3 = data4 = 0;
  342.             bit_loc = 7;
  343.             data_pointer = data_ptr + (picture_x_offset * bytes_per_pixel);
  344.             data = remap[0][*data_pointer];
  345.             for (x = image_x_offset; x < image_x_max ; x++){
  346.                 data1 |= ((data & 0x01) << bit_loc);
  347.                 data2 |= (((data & 0x02) >> 1) << bit_loc);
  348.                 data3 |= (((data & 0x04) >> 2) << bit_loc);
  349.                 data4 |= (((data & 0x08) >> 3) << bit_loc);
  350.                 if (--bit_loc < 0){
  351.                     bit_loc = 7;
  352.                     *formed_data_ptr = (unsigned char) data1;
  353.                     formed_data_ptr[maxx] = (unsigned char) data2;
  354.                     formed_data_ptr[maxx << 1] = (unsigned char) data3;
  355.                     formed_data_ptr[maxx + (maxx << 1)] = (unsigned char) data4;
  356.                     formed_data_ptr++;
  357.                     data1 = data2 = data3 = data4 = 0;
  358.                     }
  359.                 if ((h_shrink & 0xFC) != 0){
  360.                     h_shrink = zoom_inc;
  361.                     data_pointer += row_inc;
  362.                     data = remap[0][*data_pointer];
  363.                     }
  364.                 else
  365.                     h_shrink++;
  366.                 }
  367.             if (bit_loc < 7){        /* dump out last 1 .. 7 pixels */
  368.                 *formed_data_ptr = (unsigned char) data1;
  369.                 formed_data_ptr[maxx] = (unsigned char) data2;
  370.                 formed_data_ptr[maxx << 1] = (unsigned char) data3;
  371.                 formed_data_ptr[maxx + (maxx << 1)] = (unsigned char) data4;
  372.                 }
  373. #if 0
  374.             }
  375. #endif
  376.         for (zoom_row = zoom_inc; zoom_row <= 4; zoom_row++)
  377.             VGA_video_copy(drawing_row++, buffer_ptr);
  378. #else
  379.         for (zoom_row = zoom_inc; zoom_row <= 4; zoom_row++){
  380.             data_pointer = data_ptr + (picture_x_offset * bytes_per_pixel);
  381.             for (x = image_x_offset; x < image_x_max ; x++){
  382.                 put16Pixel(x, drawing_row, remap[0][*data_pointer]);
  383.                 if ((h_shrink & 0xFC) != 0){
  384.                     data_pointer += row_inc;
  385.                     h_shrink = zoom_inc;
  386.                     }
  387.                 else
  388.                     h_shrink++;
  389.                 }
  390.             drawing_row++;
  391.             }
  392. #endif
  393.         break;
  394.     case SVGA:
  395.         for (x = image_x_offset; x < image_x_max ; x++){
  396.             *formed_data_ptr++ = *data_pointer;
  397.             if ((h_shrink & 0xFC) != 0){
  398.                 data_pointer += row_inc;
  399.                 h_shrink = zoom_inc;
  400.                 }
  401.             else
  402.                 h_shrink++;
  403.             }
  404.         for (zoom_row = zoom_inc; zoom_row <= 4; zoom_row++)
  405.             video_copy(drawing_row++, buffer_ptr);
  406.         break;
  407. #ifndef small_viewer
  408.     case SVGA_15_bit:
  409.     case SVGA_16_bit:
  410.         for (x = image_x_offset; x < image_x_max ; x++){
  411.             *formed_data_int_ptr++ = *data_int_ptr;
  412.             if ((h_shrink & 0xFC) != 0){
  413.                 data_int_ptr += shrink;
  414.                 h_shrink = zoom_inc;
  415.                 }
  416.             else
  417.                 h_shrink++;
  418.             }
  419.         for (zoom_row = zoom_inc; zoom_row <= 4; zoom_row++)
  420.             video_copy(drawing_row++, buffer_ptr);
  421.         break;
  422.     case SVGA_24_bit:
  423.         for (x = image_x_offset; x < image_x_max ; x++){
  424.             *formed_data_ptr++ = *data_pointer;
  425.             *formed_data_ptr++ = *(data_pointer + 1);
  426.             *formed_data_ptr++ = *(data_pointer + 2);
  427.             if ((h_shrink & 0xFC) != 0){
  428.                 data_pointer += row_inc;
  429.                 h_shrink = zoom_inc;
  430.                 }
  431.             else
  432.                 h_shrink++;
  433.             }
  434.         for (zoom_row = zoom_inc; zoom_row <= 4; zoom_row++)
  435.             video_copy(drawing_row++, buffer_ptr);
  436. #endif
  437.     }
  438. }
  439.  
  440.  
  441.  
  442. /*
  443.  * Write some rows of output data - 16 & 256 color modes only
  444.  *
  445.  * note ------ row is not going from 0 to max because it goes in sections ------
  446.  *   so gr_row is set externally and incremented here - this allows external control
  447.  *        ie in the case of interlaced gifs  - dito for read_row
  448.  */
  449.  
  450. void put_pixel_rows (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
  451. {
  452. for (row = 0; row < num_rows; row++){
  453.     data_ptr = pixel_data[0][row];
  454.     if (enable_pan){
  455.         data_ref_ptr = *((*cinfo->emethods->access_big_sarray) (raw_pic_ptr, read_row++, TRUE));
  456.         _fmemcpy((void FAR *) data_ref_ptr, (void FAR *) data_ptr, (size_t) bytes_per_line);
  457.         }
  458.     draw_line(gr_row++, data_ptr, line_buffer_ptr);
  459.     }
  460. }
  461.  
  462.  
  463.  
  464.  
  465.  
  466. /*
  467.  * pan the 4/8/15/16/24 image from the buffer
  468.  *   no tint controls unless done thru pallet for 4/8 bit modes
  469.  */
  470.  
  471. void pan_image(decompress_info_ptr cinfo)    /* pan the image from buffer -> screen */
  472. {
  473. int actual_row, row;
  474. for (row = picture_y_offset; row < picture_y_max; row++){
  475.     actual_row = fix_order(row);
  476.     data_ptr = *((*cinfo->emethods->access_big_sarray)    (raw_pic_ptr, actual_row, FALSE));
  477.     draw_line(row, data_ptr, line_buffer_ptr);
  478.     if (allow_video_exit && kbhit()) return;
  479.     }
  480. }
  481.  
  482.  
  483.  
  484.  
  485.  
  486. #ifndef small_viewer        /* only include this in the full blown version */
  487.  
  488.  
  489.  
  490. /*
  491.  * put pixel routine for 15/16/24 bit video modes
  492.  *
  493.  * this is not designed for speed, JPEGs use a different routine
  494.  * note ------ row is not going from 0 to max because it goes in sections ------
  495.  */
  496.  
  497. void put_hi_pixel (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
  498. {
  499. unsigned int FAR * int_data_ptr;
  500.  
  501. for (row = 0; row < num_rows; row++) {
  502.     ptr0 = pixel_data[0][row];
  503.     ptr1 = pixel_data[1][row];
  504.     ptr2 = pixel_data[2][row];
  505.     if (!enable_pan)
  506.         read_row = 0;
  507.     data_ptr = data_ref_ptr = *((*cinfo->emethods->access_big_sarray) (raw_pic_ptr, read_row++, TRUE));
  508.     int_data_ptr = (unsigned int FAR *) data_ptr;
  509.  
  510.     for (col = 0; col < picture_x_size; col++){
  511.         RGB_read_and_tint();
  512. /* 16 bit red color range is wrong, all red but shading is not right */
  513. /* blue looks good ie red != 0*/
  514. /* 16 bit green intensity range is wrong - no red tint visable */
  515.         switch (video_resolution){
  516.             case SVGA_15_bit:
  517.                 *int_data_ptr = (unsigned int)(red >> 3) + ((green << 2) & 0x3e0) + ((blue << 7) & 0x7c00);
  518.                 int_data_ptr++;
  519.                 break;
  520.             case SVGA_16_bit:
  521. /*                *int_data_ptr = (unsigned int)(red >> 3) + ((green << 2) & 0x3e0) + ((blue << 7) & 0x7c00);*/
  522.                 *int_data_ptr = ((unsigned int)red >> 3) + ((unsigned int)(green << 3) & 0x7e0) + (((unsigned int)blue << 8) & 0xf800);
  523.                 int_data_ptr++;
  524.                 break;
  525.             case SVGA_24_bit:
  526.                 *data_ptr++ = red;
  527.                 *data_ptr++ = green;
  528.                 *data_ptr++ = blue;
  529.             }
  530.         }
  531.     }
  532.     draw_line(gr_row++, data_ref_ptr, line_buffer_ptr);
  533. }
  534.  
  535.  
  536.  
  537.  
  538.  
  539. /*
  540.  * tint the 15 bit image by playing with the video memory directly
  541.  * No exiting because this can only be reversed if done totally
  542.  */
  543.  
  544. void tint_15_image()
  545. {
  546. unsigned long offset, line_offset;
  547. unsigned int data;
  548. int bank;
  549. int red, green, blue;        /* colors for saving full 24 bit resolution */
  550.  
  551. bank = -1;        /* make sure bank != offset >> 16 */
  552. line_offset = (unsigned long)image_x_offset * bytes_per_pixel + (unsigned long)image_y_offset * (unsigned int)xwidth;
  553.  
  554. for (row = image_y_offset; row < image_y_max; row++){
  555.     offset = line_offset;
  556.     for (col = image_x_offset; col < image_x_max; col++){
  557.  
  558. /* do a bank check */
  559.         if ((offset >> 16) != bank){        /* ie since always start at 0 and count by 2 ... */
  560.             bank = offset >> 16;
  561.             _AX = bank;
  562.             newbank();
  563.             }
  564.  
  565.         data = peek(video_mem_seg, (unsigned int) offset);
  566.  
  567.         red = (unsigned int) (data & 0x1f);        /* convert from 5 bits to 8 */
  568.         red += (signed char) tint_table[0][red];
  569.  
  570.         green = (unsigned int) (data & 0x3e0) >> 2;
  571.         green += (signed char) tint_table[1][green];
  572.  
  573.         blue = (unsigned int) (data & 0x7c00) >> 7;
  574.         blue += (signed char) tint_table[2][blue];
  575.  
  576.         if (((red & 0xffe0) | (green | blue) & 0xff00) == 0){
  577. /*        if (red < 32 && green < 256 && blue < 256 && red >= 0 && green >= 0 && blue >= 0){*/
  578.             poke(video_mem_seg, offset, red | ((green << 2) & 0x3e0) + ((blue << 7) & 0x7c00));
  579.             }
  580.         offset += 2;
  581.         }
  582.     line_offset += maxx;
  583.     }
  584. }
  585.  
  586.  
  587.  
  588.  
  589. /*
  590.  * tint the 16 bit image by playing with the video memory directly
  591.  * No exiting because this can only be reversed if done totally
  592.  */
  593.  
  594. void tint_16_image()
  595. {
  596. unsigned long offset, line_offset;
  597. unsigned int data;
  598. int bank;
  599. int red, green, blue;        /* colors for saving full 24 bit resolution */
  600.  
  601. bank = -1;        /* make sure bank != offset >> 16 */
  602. line_offset = (unsigned long)image_x_offset * bytes_per_pixel + (unsigned long)image_y_offset * (unsigned int)xwidth;
  603.  
  604. for (row = image_y_offset; row < image_y_max; row++){
  605.     offset = line_offset;
  606.     for (col = image_x_offset; col < image_x_max; col++){
  607.  
  608. /* do a bank check */
  609.         if ((offset >> 16) != bank){        /* ie since always start at 0 and count by 2 ... */
  610.             bank = offset >> 16;
  611.             _AX = bank;
  612.             newbank();
  613.             }
  614.  
  615.         data = peek(video_mem_seg, (unsigned int) offset);
  616.  
  617.         red = (unsigned int) (data & 0x1f);        /* convert from 5 bits to 8 */
  618.         red += (signed char) tint_table[0][red];
  619.  
  620.         green = (unsigned int) (data & 0x7e0) >> 3;
  621.         green += (signed char) tint_table[1][green];
  622.  
  623.         blue = (unsigned int) (data & 0xf800) >> 8;
  624.         blue += (signed char) tint_table[2][blue];
  625.  
  626.         if (red < 32 && green < 256 && blue < 256 && red >= 0 && green >= 0 && blue >= 0){
  627.             poke(video_mem_seg, offset, red | ((green << 3) & 0x7e0) + ((blue << 8) & 0xf800));
  628.             }
  629.         offset += 2;
  630.         }
  631.     line_offset += maxx;
  632.     }
  633. }
  634.  
  635.  
  636.  
  637. /*
  638.  * tint the 24 bit image
  639.  *  do by processing video memory directly
  640.  
  641.  * - if a byte tripplet crosses a 64k boundary that pixel is not processed !
  642.  */
  643.  
  644. void tint_24_image(void)
  645. {
  646. /* offset is the byte offset into the video memory,
  647.  * line_offset is the offset at the start of the line,
  648.  * this is necessary because some cards use a line width of 1920 bytes while others use 2048
  649.  * No exiting because this can only be reversed if done totally
  650.  */
  651. unsigned long offset, line_offset;
  652. unsigned int data;
  653. int bank;
  654. int red, green, blue;        /* colors for saving full 24 bit resolution */
  655.  
  656. line_offset = (unsigned long)image_x_offset * bytes_per_pixel + (unsigned long)image_y_offset * (unsigned int)xwidth;
  657. bank = -1;        /* make sure bank != offset >> 16 */
  658.  
  659. for (row = image_y_offset; row < image_y_max; row++){
  660.     offset = line_offset;
  661.     for (col = image_x_offset; col < image_x_max; col++){
  662.  
  663. /* do a bank check */
  664.         if ((offset >> 16) != bank){
  665.             bank = offset >> 16;
  666.             _AX = bank;
  667.             newbank();
  668.             }
  669.  
  670.         if ( ((offset + 3) >> 16) == (offset >> 16) ){            /* ie if this all happens in the same bank */
  671.             red = (unsigned char) peekb(video_mem_seg, (unsigned int) offset);
  672.             red += (signed char) tint_table[0][red];
  673.  
  674.             green = (unsigned char) peekb(video_mem_seg + 1, (unsigned int) offset);
  675.             green += (signed char) tint_table[1][green];
  676.  
  677.             blue = (unsigned char) peekb(video_mem_seg + 2, (unsigned int) offset);
  678.             blue += (signed char) tint_table[2][blue];
  679.  
  680.             if (red < 256 && red >= 0 && green < 256 && green >= 0 && blue < 256 && blue >= 0){
  681.                 pokeb(video_mem_seg, offset, red);
  682.                 pokeb(video_mem_seg + 1, offset, green);
  683.                 pokeb(video_mem_seg + 2, offset, blue);
  684.                 }
  685.             }
  686.         offset += bytes_per_pixel;
  687.         }
  688.     line_offset += maxx;
  689.     }
  690. }
  691.  
  692.  
  693.  
  694. /*
  695.  * tint R, G, B seperate data streams into the red, green, blue vars
  696.  * do limiting to prevent color wraparound
  697.  * - this is used by any routine which reads the 3 * byte non-quantized data
  698.  */
  699.  
  700. void near RGB_read_and_tint(void)
  701. {
  702. int red_new, green_new, blue_new;
  703.  
  704. red = GETJSAMPLE(*ptr2++);
  705. green = GETJSAMPLE(*ptr1++);
  706. blue = GETJSAMPLE(*ptr0++);
  707.  
  708. if (tint_loaded) return;        /* shortcut if there is nothing to do */
  709.  
  710. red_new = new_tint(red, tint_factor_red) + red;
  711. green_new = new_tint(green, tint_factor_green) + green;
  712. blue_new = new_tint(blue, tint_factor_blue) + blue;
  713.  
  714. if (red_new < 256 && green_new < 256 && blue_new < 256 && red_new >= 0 && green_new >= 0 && blue_new >= 0){
  715.     red = red_new;
  716.     green = green_new;
  717.     blue = blue_new;
  718.     }
  719. }
  720.  
  721.  
  722. #else  /* if small_viewer */
  723. void put_hi_pixel (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
  724. {}
  725. void tint_15_image()
  726. {}
  727. void tint_16_image()
  728. {}
  729. void tint_24_image(void)
  730. {}
  731. #endif
  732.