home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / x / viewers / xloadimg.tar / merge.c < prev    next >
C/C++ Source or Header  |  1991-05-20  |  6KB  |  236 lines

  1. /* merge.c:
  2.  *
  3.  * merge two images
  4.  *
  5.  * jim frost 09.27.89
  6.  *
  7.  * Copyright 1989, 1990, 1991 Jim Frost.
  8.  * See included file "copyright.h" for complete copyright information.
  9.  */
  10.  
  11. #include "copyright.h"
  12. #include "image.h"
  13.  
  14. /* if merging bitmaps they don't have to be converted to
  15.  * 24-bit.  this saves a lot of space.
  16.  */
  17.  
  18. static Image *bitmapToBitmap(src, dest, atx, aty, clipw, cliph, verbose)
  19.      Image        *src, *dest;
  20.      unsigned int  atx, aty, clipw, cliph;
  21.      unsigned int  verbose;
  22. { unsigned int  destlinelen, srclinelen;
  23.   unsigned int  deststart;
  24.   unsigned int  flip;
  25.   unsigned int  x, y;
  26.   byte         *destline, *srcline;
  27.   byte          deststartmask;
  28.   byte          destmask, srcmask;
  29.   byte         *destpixel, *srcpixel;
  30.  
  31.   destlinelen= (dest->width / 8) + (dest->width % 8 ? 1 : 0);
  32.   srclinelen= (src->width / 8) + (src->width % 8 ? 1 : 0);
  33.   destline= dest->data + (aty * destlinelen);
  34.   srcline= src->data;
  35.   deststart= atx / 8;
  36.   deststartmask= 0x80 >> (atx % 8);
  37.   flip= ((*dest->rgb.red == *(src->rgb.red + 1)) &&
  38.      (*dest->rgb.green == *(src->rgb.green + 1)) &&
  39.      (*dest->rgb.blue == *(src->rgb.blue + 1)));
  40.   for (y= 0; y < cliph; y++) {
  41.     destpixel= destline + deststart;
  42.     srcpixel= srcline;
  43.     destmask= deststartmask;
  44.     srcmask= 0x80;
  45.     for (x= 0; x < clipw; x++) {
  46.       if (flip)
  47.     if (*srcpixel & srcmask)
  48.       *destpixel &= ~destmask;
  49.     else
  50.       *destpixel |= destmask;
  51.       else
  52.     if (*srcpixel & srcmask)
  53.       *destpixel |= destmask;
  54.     else
  55.       *destpixel &= ~destmask;
  56.       destmask >>= 1;
  57.       srcmask >>= 1;
  58.       if (destmask == 0) {
  59.     destmask= 0x80;
  60.     destpixel++;
  61.       }
  62.       if (srcmask == 0) {
  63.     srcmask= 0x80;
  64.     srcpixel++;
  65.       }
  66.     }
  67.     destline += destlinelen;
  68.     srcline += srclinelen;
  69.   }
  70.   if (verbose)
  71.     printf("done\n");
  72.   return(dest);
  73. }
  74.  
  75. static Image *anyToTrue(src, dest, atx, aty, clipw, cliph, verbose)
  76.      Image        *src, *dest;
  77.      unsigned int  atx, aty, clipw, cliph;
  78.      unsigned int  verbose;
  79. { Pixel         fg, bg;
  80.   unsigned int  destlinelen, srclinelen;
  81.   unsigned int  deststart;
  82.   unsigned int  x, y;
  83.   byte         *destline, *srcline;
  84.   byte         *destpixel, *srcpixel;
  85.   byte          srcmask;
  86.   Pixel         pixval;
  87.  
  88.   if (!TRUEP(dest))
  89.     dest= expand(dest);
  90.  
  91.   switch (src->type) {
  92.   case IBITMAP:
  93.     fg= RGB_TO_TRUE(src->rgb.red[1], src->rgb.green[1], src->rgb.blue[1]);
  94.     bg= RGB_TO_TRUE(src->rgb.red[0], src->rgb.green[0], src->rgb.blue[0]);
  95.     destlinelen= dest->width * dest->pixlen;
  96.     srclinelen= (src->width / 8) + (src->width % 8 ? 1 : 0);
  97.     destline= dest->data + (aty * destlinelen);
  98.     srcline= src->data;
  99.     deststart= atx * dest->pixlen;
  100.     for (y= 0; y < cliph; y++) {
  101.       destpixel= destline + deststart;
  102.       srcpixel= srcline;
  103.       srcmask= 0x80;
  104.       for (x= 0; x < clipw; x++) {
  105.     valToMem((*srcpixel & srcmask ? fg : bg), destpixel, 3);
  106.     destpixel += 3;
  107.     srcmask >>= 1;
  108.     if (srcmask == 0) {
  109.       srcpixel++;
  110.       srcmask= 0x80;
  111.     }
  112.       }
  113.       destline += destlinelen;
  114.       srcline += srclinelen;
  115.     }
  116.     break;
  117.   
  118.   case IRGB:
  119.     destlinelen= dest->width * dest->pixlen;
  120.     srclinelen= src->width * src->pixlen;
  121.     deststart= atx * dest->pixlen;
  122.     destline= dest->data + (aty * destlinelen);
  123.     srcline= src->data;
  124.  
  125.     for (y= 0; y < cliph; y++) {
  126.       destpixel= destline + deststart;
  127.       srcpixel= srcline;
  128.       for (x= 0; x < clipw; x++) {
  129.     pixval= memToVal(srcpixel, src->pixlen);
  130.     *(destpixel++)= src->rgb.red[pixval] >> 8;
  131.     *(destpixel++)= src->rgb.green[pixval] >> 8;
  132.     *(destpixel++)= src->rgb.blue[pixval] >> 8;
  133.     srcpixel += src->pixlen;
  134.       }
  135.       destline += destlinelen;
  136.       srcline += srclinelen;
  137.     }
  138.     break;
  139.  
  140.   case ITRUE:
  141.     destlinelen= dest->width * dest->pixlen;
  142.     srclinelen= src->width * src->pixlen;
  143.     deststart= atx * dest->pixlen;
  144.     destline= dest->data + (aty * destlinelen);
  145.     srcline= src->data;
  146.  
  147.     for (y= 0; y < cliph; y++) {
  148.       destpixel= destline + deststart;
  149.       srcpixel= srcline;
  150.       for (x= 0; x < clipw; x++) {
  151.     *(destpixel++)= *(srcpixel++);
  152.     *(destpixel++)= *(srcpixel++);
  153.     *(destpixel++)= *(srcpixel++);
  154.       }
  155.       destline += destlinelen;
  156.       srcline += srclinelen;
  157.     }
  158.     break;
  159.   }
  160.   if (verbose)
  161.     printf("done\n");
  162.   return(dest);
  163. }
  164.  
  165. /* put src image on dest image
  166.  */
  167.  
  168. Image *merge(dest, src, atx, aty, verbose)
  169.      Image        *dest;
  170.      Image        *src;
  171.      int           atx, aty;
  172.      unsigned int  verbose;
  173. { int clipw, cliph;
  174.   int clipped = 0;
  175.   Image *newimage;
  176.  
  177.   goodImage(dest, "merge");
  178.   goodImage(src, "merge");
  179.  
  180.   if (verbose) {
  181.     printf("  Merging...");
  182.     fflush(stdout);
  183.   }
  184.  
  185.   /* adjust clipping of src to fit within dest
  186.    */
  187.  
  188.   clipw= src->width;
  189.   cliph= src->height;
  190.   if ((atx + clipw < 0) || (aty + cliph < 0) ||
  191.       (atx >= (int)dest->width) ||
  192.       (aty >= (int)dest->height)) /* not on dest, ignore */
  193.     return;
  194.  
  195.   if (atx + clipw > dest->width)
  196.     clipw = dest->width - atx;
  197.   if (aty + cliph > dest->height)
  198.     cliph = dest->height - aty;
  199.  
  200.   /* extra clipping required for negative offsets
  201.    */
  202.  
  203.   if ( atx < 0 || aty < 0 ) {
  204.     int clipx, clipy;
  205.  
  206.     if ( atx < 0 ) {
  207.       clipx = -atx;
  208.       clipw += atx;
  209.       atx = 0;
  210.     }
  211.     else
  212.       clipx = 0;
  213.     
  214.     if ( aty < 0 ) {
  215.       clipy = -aty;
  216.       cliph += aty;
  217.       aty = 0;
  218.     }
  219.     else
  220.       clipy = 0;
  221.     
  222.     clipped = 1;
  223.     src = clip(src, clipx, clipy, clipw, cliph, verbose);
  224.   }
  225.  
  226.   if (BITMAPP(dest) && BITMAPP(src))
  227.     newimage= bitmapToBitmap(src, dest, (unsigned int)atx, (unsigned int)aty,
  228.                  clipw, cliph, verbose);
  229.   else
  230.     newimage= anyToTrue(src, dest, (unsigned int)atx, (unsigned int)aty,
  231.             clipw, cliph, verbose);
  232.   if (clipped)
  233.     freeImage(src);
  234.   return(newimage);
  235. }
  236.