//

addimage

int add2(HWND hWnd, imgdes *image1, imgdes *image2,
   imgdes *image3)
{
   int rcode;

   setimagearea(image1, 0, 0, 255, 255);
   setimagearea(image2, 0, 0, 255, 255);
   if((rcode=blur(image1, image2)) == NO_ERROR) {
      setimagearea(image3, 0, 0, 255, 255);
      if((rcode=addimage(image1, image2, image3)) != NO_ERROR)
         MessageBox(hWnd,"Error in adding images", 0, MB_OK);
      }
   else
      MessageBox(hWnd,"Error in blurring images", 0, MB_OK);
   return(rcode);
}

This example smooths image1, adds the original image to the smoothed image, and places the result in image3.




allocDIB

void CopyImageToClipboard(HWND hWnd, imgdes *image)
{
   int rcode = NO_ERROR;
   imgdes timage;
   HGLOBAL hMem;

  if(OpenClipboard(hWnd)) { // Open clipboard
     EmptyClipboard();
     // Create a new DIB to pass to the clipboard
     rcode = allocDIB(&timage, (int)image->bmh->biWidth,
        (int)image->bmh->biHeight, image->bmh->biBitCount);
     if(rcode == NO_ERROR) {
        rcode = copyimage(image, &timage);
        if(rcode == NO_ERROR) {
           // Get a handle to the new DIB
           hMem = GlobalPtrHandle(timage.bmh);
           // Unlock the handle to the DIB
           GlobalUnlock(hMem);
           // Pass the DIB to the clipboard
           SetClipboardData(CF_DIB, hMem);
           }
        }
     CloseClipboard();
     }
  if(rcode != NO_ERROR)
  MessageBox(hWnd, "Error copying DIB to clipboard", 0, MB_OK);
}

This example creates a DIB from an image and passes the DIB to the Windows clipboard.




allocimage

int loadTifImage(HWND hWnd, LPCSTR fname, imgdes *image)

   char szBuff[80];
   TiffData tdat;
   int rcode;

   // Get info on the file we're to load
   rcode = tiffinfo(fname, &tdat); // Fill structure
   if(rcode == NO_ERROR) {
   // Allocate space for an image in global memory
     rcode = allocimage(image, tdat.width, tdat.length,
       tdat.vbitcount);
   if(rcode == NO_ERROR)
      rcode = loadtif(fname, image);
   }

   // If there is an error, free image and display message
   if(rcode != NO_ERROR) {
      freeimage(image);
      wsprintf(szBuff, "Could not load %s", fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   return(rcode);
}

This example reads a TIFF file header, allocates memory to hold the image, and then loads the TIFF file.




allocimage

int AddRectToTifImage(HWND hWnd, LPCSTR fname, imgdes *image)
{
  char szBuff[80];
  TiffData tdat;
  int rcode;
  HDC hDC, hMemDC;
  HBITMAP hOldBitmap;

  // Get info on the file we're to load
  rcode = tiffinfo(fname, &tdat); // Fill structure
  if(rcode == NO_ERROR) {
     // Allocate space for an image
     rcode = allocimage(image, tdat.width, tdat.length,
        tdat.vbitcount);
     if(rcode == NO_ERROR)
        rcode = loadtif(fname, image);
     }

  // If TIF file was successfully loaded, draw rectangle
  if(rcode == NO_ERROR) {
     // Create a memory DC
     hDC = GetDC(hWnd);
     hMemDC = CreateCompatibleDC(hDC);
     if(hMemDC != 0) {
        // Select the bitmap into the DC
       hOldBitmap = SelectObject(hMemDC, image->hBitmap);

        // Draw the rect into the DIB
        Rectangle(hMemDC, 10, 10, 100, 100);

        // Restore the original bitmap
        SelectObject(hMemDC, hOldBitmap);

        // Free the memory DC
        DeleteDC(hMemDC);
        ReleaseDC(hWnd, hDC);
        }
     }
  else { // There was an error, free image and display message
     freeimage(image);
     wsprintf(szBuff, "Could not load %s", fname);
     MessageBox(hWnd, szBuff, 0, MB_OK);
     }
  return(rcode);
}

This example allocates memory to hold an image, loads a TIFF file, and draws a rectangle on the image.




andimage

int andx(HWND hWnd, imgdes *image1, imgdes *image2,
   imgdes *image3)
{
   int rcode;

   setimagearea(image1, 0, 0, 255, 255);
   setimagearea(image2, 0, 0, 255, 255);
   if((rcode=negative(image1, image2)) == NO_ERROR) {
      setimagearea(image3, 0, 0, 255, 255);
      if((rcode=andimage(image1, image2, image3)) != NO_ERROR)
         MessageBox(hWnd,"Error in ANDing images", 0, MB_OK);
      }
   else
      MessageBox(hWnd,"Error in creating negative image", 0,
      MB_OK);
   return(rcode);
}

This example creates the negative of image1, ANDs the original image with the negative, and places the result in image3.




blur



blurthresh

void blurit(HWND hWnd, imgdes *image)
{
   int rcode, stx=0, sty=0, endx=255, endy=243, thresh=128;

   setimagearea(image, stx, sty, endx/2 - 1, endy);
   if((rcode=blur(image, image)) == NO_ERROR) {
      setimagearea(image, endx/2, sty, endx, endy);
      if((rcode=blurthresh(thresh, image, image)) == NO_ERROR) {
         setimagearea(image, stx, sty, endx, endy);
         if((rcode=savebif("Blurred.bif", image)) != NO_ERROR)
            MessageBox(hWnd,"Error in saving image", 0, MB_OK);
         }
      else
         MessageBox(hWnd,"Error at blurthresh()", 0, MB_OK);
      }
   else
      MessageBox(hWnd,"Error at blur", 0, MB_OK);
}

This example smooths the left half of the image, smooths the right half of the image using a threshold and saves the entire image.




bmpinfo

int info_bmp(LPCSTR fname)
{
   char szBuff[512];
   BITMAPINFOHEADER bdat;   // Reserve space for struct
   int rcode;

   // Make sure file exists and get info on it
   if((rcode = bmpinfo(fname, &bdat)) == NO_ERROR) {
      wsprintf((LPSTR)szBuff, (LPSTR)"File name: %s"
      "\nImage width: %ld, Image length: %ld"
      "\nPlanes: %d"
      "\nBitCount: %d"
      "\nHeader size: %ld"
      "\nCompression: %ld, Image size: %ld"
      "\nColors used: %ld, Colors Important: %ld",
         (LPSTR)fname, bdat.biWidth, bdat.biHeight,
         bdat.biPlanes, bdat.biBitCount, bdat.biSize,
         bdat.biCompression, bdat.biSizeImage,
         bdat.biClrUsed, bdat.biClrImportant);
      MessageBox(0, szBuff, (LPSTR)"File information", MB_OK);
      }
   return(rcode);
}

This example displays information about a BMP file.




bmpinfofrombuffer



loadbmpfrombuffer

example coming soon


brightenmidrange

void raisebrightness4printing(HWND hWnd, imgdes *image)
{
   HCURSOR hSaveCursor;

   // Display hourglass cursor 
   hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
   if(brightenmidrange(image, image) !=  NO_ERROR)
      MessageBox(hWnd,"Error in raising brightness", 0, MB_OK);
   SetCursor(hSaveCursor); // Restore cursor 
}

This example brightens an image before printing.




calcavglevel

int trace(HWND hWnd, imgdes *image1, imgdes *image2)
{
   int rcode, redval, grnval, bluval;

   rcode = calcavglevel(image1, &redval, &grnval, &bluval);
   if(rcode == NO_ERROR) {
      if((rcode=kodalith(redval, image1, image2)) == NO_ERROR) {
         if((rcode=outline(image2, image2)) != NO_ERROR)
            MessageBox(hWnd, "Error at outline()", 0, MB_OK);
         }
      else
         MessageBox(hWnd, "Error at kodalith", 0, MB_OK);
      }
   else
      MessageBox(hWnd,(LPSTR)"Error at calcavglevel()", 0, MB_OK);
   return(rcode);
}

This example calculates an average brightness level to create a kodalith and then outlines the image.




calchisto



drawhisto

void DrawHistogram(HWND hHistoWnd, imgdes *image)
{
   PAINTSTRUCT ps;   // Holds PAINT info
   HDC hDC;
   int rcode=NO_ERROR;
   RECT rect;
   long near *redtab, near *grntab, near *blutab;

   // Allocate space for the 3 histo tables
   if((redtab = (long near *)LocalAlloc(LPTR, 3 * 256 *
         sizeof(long))) == NULL)
      MessageBox(hHistoWnd,"Insufficient memory for histo tables",
         0, MB_OK);
   else {
      // Assign histo table pointers
      grntab = &redtab[256];
      blutab = &redtab[512];
      hDC = BeginPaint(hHistoWnd, &ps);
      // Calculate the histogram
      rcode = calchisto(image, redtab, grntab, blutab);
      if(rcode == NO_ERROR) {
         // Draw the histogram in the window
         GetClientRect(hHistoWnd, &rect);
         rcode = drawhisto(hDC, &rect, image->bmh->biBitCount,
            redtab, grntab, blutab);
         }
      EndPaint(hHistoWnd, &ps);
      LocalFree((HLOCAL)redtab);
      if(rcode != NO_ERROR)
         MessageBox(hHistoWnd, "Error in displaying histogram",
            0, MB_OK);
      }
}

This example calculates and displays the histogram of an image area.




calchistorgb

drawhisto

void DrawHistogramRGB(HWND hHistoWnd, imgdes *image)
{
   PAINTSTRUCT ps;   // Holds PAINT info
   HDC hDC;
   int rcode = NO_ERROR;
   RECT rect;
   long near *redtab, near *grntab, near *blutab;

   // Interpret 8-bit palette color image as RGB image
   int histoMode = PALETTEIMAGEASRGB;

   // Allocate space for the 3 histo tables
   if((redtab = (long near *)LocalAlloc(LPTR, 3 * 256 *
     sizeof(long))) == NULL)
   MessageBox(hHistoWnd, "Insufficient memory for histo
     tables",0, MB_OK);
   else {
      // Assign histo table pointers
      grntab = &redtab[256];
      blutab = &redtab[512];
      hDC = BeginPaint(hHistoWnd, &ps);
      // Calculate the histogram
      rcode = calchistorgb(image, redtab, grntab, blutab,
         histoMode);
      if(rcode == NO_ERROR) {
         int bitcount = image->bmh->biBitCount;
         // Force 24-bit display if image is palette color and
         // calchistorgb mode is "palette image as RGB"
         if((image->imgtype & IMGTYPE_GRAYSCALE) == 0 &&
            histoMode == PALETTEIMAGEASRGB)
            bitcount = 24;
         // Draw the histogram in the window
        GetClientRect(hHistoWnd, &rect);
        rcode = drawhisto(hDC, &rect, bitcount, redtab, grntab,
           blutab);
        }
     EndPaint(hHistoWnd, &ps);
     LocalFree((HLOCAL)redtab);
     if(rcode != NO_ERROR)
        MessageBox(hHistoWnd, "Error in displaying histogram", 0,
           MB_OK);
     }
  }

This example calculates and displays the histogram of an image area.




changebright

void change_bright(HWND hWnd, imgdes *image)
{
   HCURSOR hSaveCursor;

   // Display hourglass cursor 
   hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));

   if(changebright(5, image, image) !=  NO_ERROR)
      MessageBox(hWnd,"Error in changing brightness", 0, MB_OK);
   SetCursor(hSaveCursor); // Restore cursor 
}

This example brightens an image by 5 each time it is called.




clienttoimage

int CaptureScreenClient(HWND hWnd)
{
   int rcode;
   imgdes timage;
   LPCSTR fname = "client.tif";

   // Capture window as Victor image
   rcode = clienttoimage(hWnd, &timage);
   if(rcode == NO_ERROR) {
      // Save captured client area
      rcode = savetif(fname, &timage, 0);
      // Release memory allocated by clienttoimage()
      freeimage(&timage);
      }
   return(rcode)
}

This example captures a window's client area and saves it as a TIFF file.




colordither



colorscatter



copyimgdes

int CreateImage8(HWND hWnd, imgdes *srcimg, imgdes *desimg,
      int *freeflag)

{
   int DisplayBits, palmode, rcode = NO_ERROR;
   HDC hdc;
   imgdes timage;

   // Assume an image buffer will not be allocated
   *freeflag = 0;
   // Determine display adapter capabilities
   hdc = GetDC(hWnd);
   DisplayBits = GetDeviceCaps(hdc, BITSPIXEL);
   ReleaseDC(hWnd, hdc);

   // To view the entire image, use a temporary image descriptor and set the image area to the entire image 
   copyimgdes(srcimg, &timage);
   setimagearea(&timage, 0, 0,
      (unsigned)timage.bmh->biWidth - 1,
      (unsigned)timage.bmh->biHeight - 1);

   // If we're displaying a 24-bit image on an 8-bit display adapter, create a temporary 8-bit image for
      display
   if(srcimg->bmh->biBitCount == 24 && DisplayBits <= 8) {
      if((rcode=allocimage(desimg,
         (int)timage.bmh->biWidth,
         (int)timage.bmh->biHeight, 8)) == NO_ERROR) {
         palmode = DisplayBits == 8 ? COLORDITHER256 :
           COLORDITHER16;

         // Quick dither representation of 24-bit image
         // (Or use colorscatter)
         rcode = colordither(&timage, desimg, palmode);

         // If error, free allocated memory
         if(rcode != NO_ERROR)
            freeimage(desimg);
         else // Set freeflag=1 to show new image buffer allocated
            *freeflag = 1;
         }
      }
   else
      copyimgdes(&timage, desimg);
   return(rcode);
}

This example creates a new 8-bit color dithered image if the source image is a 24-bit RGB image and the display adapter is limited to 256 or fewer colors.




colortogray

void makegray4printing(HWND hWnd, imgdes *image)
{
   HCURSOR hSaveCursor;

   // Display hourglass cursor 
   hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
   if(colortogray(image, image) !=  NO_ERROR)
      MessageBox(hWnd,"Error in creating gray image", 0, MB_OK);
   SetCursor(hSaveCursor); // Restore cursor 
}

This example converts a palette color image to grayscale for printing.




convert1bitto8bit

int outline1bpp(HWND hWnd, LPCSTR fname,
   imgdes *image) // Image is 1 bpp
{
   int rcode, mode = 2;   // Use threshold conversion mode
   imgdes timage;   // Temp 8-bit image

   // Load a 1-bit TIFF image
   rcode = loadtif(fname, image);
   if(rcode != NO_ERROR)
      MessageBox(hWnd, "Error in loading file", 0, MB_OK);
   else {
      // Allocate space for 8-bit temp image
      rcode = allocimage(&timage, (int)image->bmh->biWidth,
         (int) image->bmh->biHeight, 8);
      if(rcode != NO_ERROR)
         MessageBox(hWnd, "Not enough memory for temp image",
            0, MB_OK);
      else {  // Convert 1-bit to 8-bit image
         rcode = convert1bitto8bit(image, &timage);
         if(rcode != NO_ERROR)
            MessageBox(hWnd, "Error in converting image", 0,
               MB_OK);
         else {  // Outline image
            outline(&timage, &timage);
            // Convert 8-bit to 1-bit image
            convert8bitto1bit(mode, &timage, image);
            // Save as a 1-bit TIFF file, no compression
            rcode = savetif(fname, image, 0);
            if(rcode != NO_ERROR)
               MessageBox(hWnd, "Could not save image", 0, MB_OK);
            }
         freeimage(&timage);
         }
      }
   return(rcode);
}

This example loads a 1-bit per pixel image, converts it to an 8-bit per pixel image, outlines it, converts it back to 1-bit, and finally saves it as a TIFF file with the same filename.




convert1bitto8bitsmooth



convert8bitto1bit

int scaletogray(HWND hWnd, LPCSTR fname,
   imgdes *image) // Image is 1 bpp
{
   int rcode;   // Use threshold conversion mode
   imgdes timage;   // Temp 8-bit image

   // Load a 1-bit TIFF image
   rcode = loadtif(fname, image);
   if(rcode != NO_ERROR)
      MessageBox(hWnd, "Error in loading file", 0, MB_OK);
   else {
      // Allocate space for 8-bit temp image
      rcode = allocimage(&timage, (int)image->bmh->biWidth,
         (int) image->bmh->biHeight, 8);
      if(rcode != NO_ERROR)
         MessageBox(hWnd, "Not enough memory for temp image", 0, MB_OK);
      else {  // Convert 1-bit to 8-bit image with smoothing
         rcode = convert1bitto8bitsmooth(image, &timage);
         if(rcode != NO_ERROR)
            MessageBox(hWnd, "Error in converting image", 0, MB_OK);
         else {  // Replace original with smoothed 8-bit version
            freeimage(image);   // free original image
            // Replace original image data with that describing the smoothed 8-bit image
            copyimgdes(&timage, image);  // copy data structure info
            }
         }
      }
   return(rcode);
}

This example loads a 1-bit per pixel image and converts it to a smoothed 8-bit per pixel image.




convertgray8to16



convertgray16to8

int process16bitGrayTIFF(LPCSTR fname)
{
   int rcode;
   TiffData tdat;
   imgdes timage;

   rcode = tiffinfo(fname, &tdat); // Fill structure
   if(rcode == NO_ERROR &&
      // Make sure image to load is 16-bit grayscale
      tdat.BitsPSample == 16 && tdat->SamplesPPixel == 1)
      // Allocate memory for image storage
      rcode = allocimage(&timage, tdat.width, tdat.length,
tdat.vbitcount);
      if(rcode == NO_ERROR)
         // Read in a 16-bit grayscale TIFF file
         rcode = loadtif(fname, &timage);
         if(rcode == NO_ERROR) {
            imgdes nimage;
            allocimage(&nimage, tdat.width, tdat.length, 8);
            // Convert image to 8-bit
            rcode = convertgray16to8(&timage, &nimage);
            if(rcode == NO_ERROR) {
               // Process image
               histoequalize(&nimage, &nimage);
               // Convert image back to 16-bits
               convertgray8to16(&nimage, &timage);
               // Save processed 16-bit image
               rcode = savetif(fname, &timage, 0);
               freeimage(&nimage); // Release memory allocated for 8-bit image
               }
            }
         // Release memory allocated for 16-bit image
         freeimage(&timage);
         }
      }
   return(rcode)
}

This function loads a 16-bit grayscale image, converts it to 8-bits, performs image processing on it, converts it back to a 16-bit image, and saves it.




convertpaltorgb

int saveasRGB(HWND hWnd, LPCSTR fname, imgdes *srcimg)
{
   int rcode, rows, cols, compress=0;
   char str[50];
   imgdes resimg;

   rows = srcimg->endy - srcimg->sty + 1;
   cols = srcimg->endx - srcimg->stx + 1;
   rcode = allocimage(&resimg, cols, rows, 24);
   if(rcode != NO_ERROR)
      MessageBox(hWnd, "Could not allocate memory", 0, MB_OK);
   else {
      rcode = convertpaltorgb(srcimg, &resimg);
      if(rcode == NO_ERROR) {
         wsprintf(str, "Saving %s as 24-bit TGA file",
            (LPCSTR)fname);
         MessageBox(hWnd, str, 0, MB_OK);
         rcode = savetga(fname, &resimg, compress);
         if(rcode != NO_ERROR)
            MessageBox(hWnd, "Error in saving file", 0, MB_OK);
         }
      else MessageBox(hWnd, "Error converting palette "
         "color image to RGB image", 0, MB_OK);
      freeimage(&resimg);
      }
   return(rcode);
}

This example saves an 8-bit image as a 24-bit Targa file.




convertrgbtopal

int qualityview(HWND hWnd, imgdes *srcimg)
{
   int rcode, rows, cols;
   HDC hDC;
   HPALETTE hpal;
   imgdes resimg;
   PAINTSTRUCT ps;

   rows = srcimg->endy - srcimg->sty + 1;
   cols = srcimg->endx - srcimg->stx + 1;
   rcode = allocimage(&resimg, cols, rows, 8);

   if(rcode == NO_ERROR) {
      rcode = convertrgbtopal(235, srcimg, &resimg);
      if(rcode != NO_ERROR)
         MessageBox(hWnd,
         "Could not convert RGB to 8-bit image", 0, MB_OK);
      else {
         hDC = BeginPaint(hWnd, &ps);
         // Display the image at (0,0) 
         rcode = viewimage(hWnd, hDC, &hpal, 0, 0, &resimg);
         EndPaint(hWnd, &ps);
         if(rcode != NO_ERROR)
            MessageBox(hWnd, "Error in displaying image", 0,
               MB_OK);
         }
      DeleteObject(hpal);
      freeimage(&resimg);
      }
   return(rcode);
}

This example converts an RGB image to an 8-bit palette color image containing 235 colors and displays it.




convertrgbtopalex

int qualityviewex(HWND hWnd, imgdes *srcimg)
{
   int rcode, rows, cols;
   HDC hDC;
   HPALETTE hpal;
   imgdes resimg;
   PAINTSTRUCT ps;
   int colredmode = CR_TSDDIFF;

   rows = srcimg->endy - srcimg->sty + 1;
   cols = srcimg->endx - srcimg->stx + 1;
   rcode = allocimage(&resimg, cols, rows, 8);

   if(rcode == NO_ERROR) {
      rcode = convertrgbtopalex(235, srcimg, &resimg,
         colredmode);
      if(rcode != NO_ERROR)
         MessageBox(hWnd,
         "Could not convert RGB to 8-bit image", 0, MB_OK);
      else {
         hDC = BeginPaint(hWnd, &ps);
         // Display the image at (0,0) 
         rcode = viewimage(hWnd, hDC, &hpal, 0, 0, &resimg);

         EndPaint(hWnd, &ps);
         if(rcode != NO_ERROR)
            MessageBox(hWnd, "Error in displaying image", 0,
               MB_OK);
         }
      DeleteObject(hpal);
      freeimage(&resimg);
      }
   return(rcode);
}

This example converts an RGB image to an 8-bit palette color image containing 235 colors and displays it.




copyimage

int MakeBackUp(imgdes *image, imgdes *backup, RECT *backrect)
{
   int rcode, rows, cols;

   rows = image->endy - image->sty + 1;
   cols = image->endx - image->stx + 1;
   // If an old backup exists, delete it
   if(backup->bmh != 0)
      freeimage(backup);
   // Allocate our backup DIB
   if((rcode=allocimage(backup, cols, rows,
      image->bmh->biBitCount)) == NO_ERROR) {
      // Save the coords of where to place the image area
      imageareatorect(image, backrect);
      // Copy the image area into the backup buffer
      rcode = copyimage(image, backup);
      }
   return(rcode);
}

This example makes a backup copy of an image area and palette.




copyimagebits

int PasteBackUp(imgdes *backup, RECT *backrect, imgdes *image)
{
#define NO_BACKUP -3
   int rcode;


   // Make sure a backup image area exists
   if(backup->bmh == 0)
      return(NO_BACKUP);
   // Restore the previous image area
   recttoimagearea(backrect, image);
   rcode = copyimagebits(backup, image);
   return(rcode);
}

This example pastes a backup copy of an image area into an image buffer.




copyimagepalette

void dupimagepalette(int numcolors, imgdes *srcimg, imgdes *resimg)
{
   int oldcolors;

   oldcolors = srcimg->colors;
   srcimg->colors = numcolors;
   copyimagepalette(srcimg, resimg);
   srcimg->colors = oldcolors;
}

This example copies a portion of a color palette from one image to another.




cover

int coverneg(HWND hWnd, imgdes *image1, imgdes *image2,
   imgdes *image3)
{
   int rcode, threshold=68;

   if((rcode=negative(image1, image2)) == NO_ERROR) {
      if((rcode=cover(threshold,image1, image2, image3))
         != NO_ERROR)
         MessageBox(hWnd,"Error in covering image", 0, MB_OK);
      }
   else
      MessageBox(hWnd,"Error in creating negative image", 0,
         MB_OK);
   return(rcode);
}

This example creates the negative of image1, and covers the original image with the negative, and places the result in image3.




coverclear

int addShadowWithCoverClear(imgdes *srcimg, imgdes *desimg)
{
   imgdes tmpsrc;
   // Drop shadow at horiz offset 10, vert offset 5
   int hoffset = 10, voffset = 5;
   int rcode, cols, rows;
   long transcolor = 0xffffff; // White

   cols = CALC_WIDTH(srcimg); // Macros in VICDEFS.H
   rows = CALC_HEIGHT(srcimg);

   // Create the shadow in a temp buffer
   rcode = allocimage(&tmpsrc, cols, rows, srcimg->bmh->biBitCount);
   if(rcode == NO_ERROR) {
      zeroimage(255, &tmpsrc); // Set all pixels to white
      tmpsrc.stx = hoffset;
      tmpsrc.sty = voffset;
      copyimage(srcimg, &tmpsrc); // Copy src image to offset pos

      tmpsrc.stx = 0;
      tmpsrc.sty = 0;
      kodalith(255, &tmpsrc, &tmpsrc); // Turn all pixels not white
to black
      changebright(64, &tmpsrc, &tmpsrc); // Black -> dark gray
      for(j=0; j<25; j++) // Simulate gaussian blur
         blur(&tmpsrc, &tmpsrc);
      // Cover the shadow with the original image
      rcode = coverclear(transcolor, &tmpsrc, srcimg, desimg);
      freeimage(&tmpsrc); // Delete temp image
      }
   return(rcode);
}

This example creates a drop shadow of all non-white pixels in the image.




ddbtoimage

int SaveBitmapToTiffFile(HBITMAP hBitmap, HPALETTE hPal)
{
   int rcode;
   imgdes timage;
   LPCSTR fname = "bitmap.tif";
   
   rcode = ddbtoimage(hBitmap, hPal, &timage);
   if(rcode == NO_ERROR) {
      // Save captured image
      rcode = savetif(fname, &timage, 0);
      freeimage(&timage);
      }
   return(rcode);
}

This example saves a device dependent bitmap as a TIFF file.




defaultpalette

int defaultpaletteview(HWND hWnd, imgdes *srcimg)
{
   int rcode, rows, cols;
   HDC hDC;
   HPALETTE hpal;
   imgdes resimg;
   PAINTSTRUCT ps;

   rows = srcimg->endy - srcimg->sty + 1;
   cols = srcimg->endx - srcimg->stx + 1;
   // Allocate temporary 8-bit image for viewing
   rcode = allocimage(&resimg, cols, rows, 8);
   if(rcode == NO_ERROR) {
      // Create default palette in result image
      defaultpalette(&resimg);                 
      // Force 24-bit image to use default standard palette
      rcode = matchcolorimage(srcimg, &resimg);
      if(rcode != NO_ERROR)
         MessageBox(hWnd, 
         "Could not convert RGB to 8-bit image", 0, MB_OK);
      else {
         hDC = BeginPaint(hWnd, &ps);
         // Display the image at (0,0) 
         rcode = viewimageex(hWnd, hDC, &hpal, 0, 0, &resimg, 0,
            0, VIEWDITHER);   
         EndPaint(hWnd, &ps);
         if(rcode != NO_ERROR)
            MessageBox(hWnd, "Error displaying image", 0, MB_OK);
         }
      DeleteObject(hpal);            
      // Release the temporary 8-bit image
      freeimage(&resimg);
      }
   return(rcode);
}  

This example converts an RGB image to an 8-bit palette color image with the default standard palette for display.




dibsecttoimage

int SaveDIBSectToTiffFile(HBITMAP hBitmap)
{
   int rcode;
   imgdes timage;
   LPCSTR fname = "bitmap.tif";
   
   rcode = dibsecttoimage(hBitmap, &timage);
   if(rcode == NO_ERROR) {
      // Save captured image
      rcode = savetif(fname, &timage, 0);
      freeimage(&timage);
      }
   return(rcode);
}

This example saves a DIB section as a TIFF file.




dibtobitmap

int DrawBitmap(HDC hdc,
   int xpos, int ypos, // Horiz, vert displacement to 
   imgdes *image)      //  first visible pixel
{
   HDC hdcMem;
   HBITMAP hBitmap, hBitOld;   BITMAP bmap;
   int rcode;
   SetWindowOrgEx(hdc, xpos, ypos, NULL);   // For scrolling
   // Create memory DC
   hdcMem = CreateCompatibleDC(hdc);
   // Create a bitmap of the entire image
   rcode = dibtobitmap(hdc, (unsigned char *)image->bmh,
      &hBitmap);
   if(rcode == NO_ERROR) {
      // Select entire bitmap into the memory DC
      hBitOld = SelectObject(hdcMem, hBitmap);
      // Get bitmap's width and length
      GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bmap);
      // Move memory DC to the screen
      BitBlt(hdc, 0, 0, bmap.bmWidth, bmap.bmHeight,
         hdcMem, 0, 0, SRCCOPY);
      // Restore original bitmap to memory DC
      SelectObject(hdcMem, hBitOld);
      DeleteDC(hdcMem);         // Delete memory DC
      Delete Object(hBitmap);   // Release bitmap 
      }
   return(rcode);
}

This example creates a device dependent bitmap from a DIB and transfers it to a device context.




dibtoimage

int GetClipping(HWND hwnd, imgdes *image)
{
#define NO_CLIPBRD_DIB -38
#define NO_CLIPBRD -39
   unsigned char *dib;
   int rcode=NO_ERROR, oclip;
   HGLOBAL hMem;

   // Open clipboard
   if((oclip = OpenClipboard(hwnd)) != 0) {
      // Get DIB from clipboard
      if((hMem = GetClipboardData(CF_DIB)) != 0) {
         // Get address of DIB
         dib = (unsigned char *)GlobalLock(hMem);
         // Create a new image from the DIB
         rcode = dibtoimage(dib, image);
         }
      else 
         rcode = NO_CLIPBRD_DIB;   // No DIB on clipboard
      }
   else
      rcode = NO_CLIPBRD;   // Could not open clipboard
   if(hMem) // Unlock memory before closing the clipboard
      GlobalUnlock(hMem);   
   if(oclip) 
      CloseClipboard();      // Close the clipboard
   return(rcode);
}

This example creates an image from a DIB on the clipboard.




dilate

int darkenByDilation(HWND hWnd, imgdes *image)
{
   int rcode, amount = 200;

   rcode = dilate(amount, image, image);
   if(rcode != NO_ERROR)
      MessageBox(hWnd, "Error in darken by dilation", 0, MB_OK);
   return(rcode); 
}

This example darkens an image using dilation.




divide



multiply

int posterize(HWND hWnd, imgdes *image1, imgdes *image2)
{
   int rcode, factor=32;
   
   if((rcode=divide(factor, image1, image2)) == NO_ERROR) {
      if((rcode=multiply(factor, image2, image2)) != NO_ERROR)
         MessageBox(hWnd,"Error at multiply", 0, MB_OK);
      }
   else
      MessageBox(hWnd,"Error at divide", 0, MB_OK);
   return(rcode);
}

This example divides an image by 32, multiplies it by 32, and places the result in image2 to create an 8-level posterization effect.




erode

int brightenByErosion(HWND hWnd, imgdes *image)
{
   int rcode, amount = 200;

   rcode = erode(amount, image, image);
   if(rcode != NO_ERROR)
      MessageBox(hWnd, "Error in brighten by erosion", 0, MB_OK);
   return(rcode); 
}

This example brightens an image using erosion.




exchangelevel

int hilite(HWND hWnd, imgdes *image)
{
   int rcode, white=255, black=0;
   
   if((rcode=exchangelevel(20, 25, white, image, 
      image)) == NO_ERROR) {
      if((rcode=exchangelevel(26,30, black, image, 
         image)) != NO_ERROR)
         MessageBox(hWnd,"Error at setting black", 0, MB_OK);
      }
   else
      MessageBox(hWnd,"Error at setting white", 0, MB_OK);
   return(rcode);
}

This example sets pixels between 20 - 25 to white, and pixels between 26 - 30 to black.




expandcontrast

int contrast(HWND hWnd, imgdes *image)
{
   int rcode, ravg, gavg, bavg, val, low, high;

   rcode = calcavglevel(image, &ravg, &gavg, &bavg);   
   if(rcode == NO_ERROR) { // Make sure avg is valid 
      val = (ravg * 25 / 100); 
      low = ravg - val; 
      high = (val+ravg > 255) ? 255 : (ravg+val);
      if((rcode=expandcontrast(low, high, image, 
         image)) != NO_ERROR)
         MessageBox(hWnd,"Error in expanding contrast", 0, MB_OK);
      }
   else 
      MessageBox(hWnd,"Error at calcavglevel()", 0, MB_OK);
   return(rcode); 
}

This example increases the contrast based on the average brightness value.




flipimage

int flip(HWND hWnd, imgdes *image1, imgdes *image2)
{
   int rcode;
   LPCSTR fname="tree.gif";
   
   if((rcode=loadgif(fname, image1)) == NO_ERROR) {
      if((rcode==flipimage(image1, image2)) != NO_ERROR)
         MessageBox(hWnd,"Error in flipping image", 0, MB_OK);
      }
   else
      MessageBox(hWnd,"Error in loading file", 0, MB_OK);
   return(rcode); 
}

This example loads an image and places a flipped copy in another buffer.




imageareatorect



freeimage

int MakeBackUp(imgdes *image, imgdes *backup, RECT *backrect)
{
   int rcode, rows, cols;

   rows = image->endy - image->sty + 1;
   cols = image->endx - image->stx + 1;
   // If an old backup exists, delete it
   if(backup->bmh)
      freeimage(backup);
   // Allocate our backup DIB
   if((rcode=allocimage(backup, cols, rows, 
      image->bmh->biBitCount)) == NO_ERROR) {
      // Save original image area coordinates 
      imageareatorect(image, backrect);
      // Copy the image area into the backup buffer
      rcode = copyimage(image, backup);
      }
   return(rcode);
}

This example makes a backup copy of an image area and palette.




gammabrighten

void gamma_correction(HWND hWnd, imgdes *image)
{
   HCURSOR hSaveCursor;
   double gamma = 0.5;

   // Display hourglass cursor  
   hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));

   if(gammabrighten(gamma, image, image) !=  NO_ERROR)
      MessageBox(hWnd,"Error in gamma correction", 0, MB_OK);
   SetCursor(hSaveCursor); // Restore cursor 
}

This example brightens an image by applying a gamma correction of 0.5 each time it is called.




getgifcomment

void readgifcomment(HWND hWnd, char *fname)
{
   int rcode, comlen;
   char buff[80], near *combuff;

   rcode = getgifcomment(fname, NULL, 0); // Get comment length  
   switch(rcode) {
      case(BAD_OPN):
         wsprintf(buff, "Cannot open %s", (LPSTR)fname); break;
      case(BAD_GIF):
         wsprintf(buff, "Bad GIF: %s", (LPSTR)fname); break;
      case(0):
         wsprintf(buff, "No comment in %s", (LPSTR)fname); break;
      default:  // Getgifcomment() returned length of comment
         comlen = rcode;   // Save length of comment
         // Allocate space for comment string
         combuff = (char near *)LocalAlloc(LPTR, comlen + 1);
         if(combuff == NULL) {
            wsprintf(buff, "Insufficient memory");
            rcode = BAD_MEM;
            }
         else {    // Get the comment
            getgifcomment(fname, combuff, comlen + 1);
            // Display comment in message box
            MessageBox(hWnd, combuff, 0, MB_OK);
            LocalFree((HLOCAL)combuff);
            }
      }
   if(rcode <= 0) // If error, display error message
      MessageBox(hWnd, buff, 0, MB_OK);
}

This example reads and displays a comment string in a GIF file.




getpixelcolor

void get_icolumn(HWND hWnd, imgdes *image, int xx, int yy)
{
#define GET_BLU(c) (int)(((c) >> 16) & 0xff)
#define GET_GRN(c) (int)(((c) >> 8) & 0xff)
#define GET_RED(c) (int)((c) & 0xff)
   long color;
   int red, grn, blu;
   char szBuff[80];
   char *str;

   color = getpixelcolor(image, xx, yy);
   if(color >= 0) {   // Indicates no errors
      if(image->bmh->biBitCount <= 8) 
         wsprintf(szBuff, 
         "Color value at (%d,%d) is %d, %d bpp", xx, yy,
          (int)color, (int)image->bmh->biBitCount);
      else { // 24-bit image
         blu = GET_BLU(color);
         grn = GET_GRN(color);
         red = GET_RED(color);
         wsprintf(szBuff, "Color value at (%d,%d) is red: %d, "
            "green: %d, blue: %d, %d bpp", xx, yy, red, grn, blu, 
            (int)image->bmh->biBitCount);
         }
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   else {  // Error if color < 0
      switch((int)color) {  // Assign error message
         case BAD_RANGE: str="Range error";
         case BAD_BPP: str="Bits per pixel not 1, 8, or 24";
         }
      MessageBox(hWnd, str, 0, MB_OK);
      }
}

This example displays the color of a pixel and the bits per pixel of the image.




getpngcomment

void readAPNGComment(HWND hWnd, char *fname)
{
   int rcode, comlen;
   char buff[80], near *combuff;

   // Get comment length  
   rcode = getpngcomment(fname, "Comment", 0, 0);
   switch(rcode) {
      case(BAD_OPN):
         wsprintf(buff, "Cannot open %s", (LPSTR)fname); break;
      case(BAD_PNG):
         wsprintf(buff, "Bad PNG: %s", (LPSTR)fname); break;
      case(0):
         wsprintf(buff, "No comment in %s", (LPSTR)fname); break;
      default:  // Getpngcomment() returned length of comment
         comlen = rcode;   // Save length of comment
         // Allocate space for comment string
         combuff = (char near *)calloc(comlen + 1, sizeof(char));
         if(combuff == NULL) {
            wsprintf(buff, "Insufficient memory");
            rcode = BAD_MEM;
            }
         else {    // Get the comment
            getgifcomment(fname, combuff, comlen + 1);
            // Display comment in message box
            MessageBox(hWnd, combuff, 0, MB_OK);
            free(combuff);
            }
      }
   if(rcode <= 0) // If error, display error message
      MessageBox(hWnd, buff, 0, MB_OK);
}

This example reads and displays a comment string in a PNG file.




gifinfo

void gifsize(HWND hWnd, char *fname)
{
   GifData gdat;             // Reserve space for structure 
   int rcode;
   char szBuff[80];

   rcode = gifinfo(fname, &gdat);
   if(rcode == BAD_OPN) {
      wsprintf(szBuff, "Could not find %s", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   else if(rcode == BAD_GIF) {
      wsprintf(szBuff, "%s is not a GIF file", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   else {
      wsprintf(szBuff, 
         "%s image dimensions: Width=%d, Length=%d",
         (LPSTR)fname, gdat.width, gdat.length);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
}

This example reads a GIF file and prints the image size.




gifinfoframe

// Load a frame from a GIF file
int load_a_frame(LPTSTR fname, int framenumber, imgdes *image)
{
   GifData gifdat; 
   int rcode;
   imgdes tempimage;

   int totalFrames;
   GifGlobalData gdata;
   GifFrameData fdata;

   rcode = gifframecount(fname, &totalFrames);  // Count the number of frames

   if(framenumber < totalFrames);
      rcode = gifinfoframe(fname, &gifdat, &gdata, &fdata, framenumber);

   if(rcode == NO_ERROR) {
      // Allocate an image buffer to hold the frame
      if((rcode = allocimage(&tempimage, gifdat.width, gifdat.length, gifdat.vbitcount)) == NO_ERROR)
            rcode = loadgifframe(fname, &tempimage, &gdata, &fdata]);
      }

   // Replace original image with this new image of a single gif frame
   if(rcode == NO_ERROR || rcode == BAD_DATA) {
      freeimage(image);
      copyimgdes(&tempimage, image);
      rcode = NO_ERROR; // Set rcode to NO_ERROR if file contained invalid data
      }
   return(rcode);
}

This example loads a single frame from a GIF file.




gifinfoframefrombuffer

No Example!!!

histobrighten

void brightenhisto(HWND hWnd, imgdes *image)
{
   if(histobrighten(image, image) !=  NO_ERROR)
      MessageBox(hWnd,"Error in brightening image", 0, MB_OK);
}

This example brightens an image and increases contrast.




histoequalize

void equalizehisto(HWND hWnd, imgdes *image)
{
   if(histoequalize(image, image) !=  NO_ERROR)
      MessageBox(hWnd,"Error in equalizing histogram", 0, MB_OK);
}

This example brightens an image through histogram equalization.




hsv2rgb

void hsv_to_rgb(int colors, // Number of HSVTRIPLEs to convert
   HSVTRIPLE *hsvtab, imgdes *image)
{
   hsv2rgb(hsvtab, image->palette, colors);
   image->colors = colors;
}

This example converts an HSV table to a color palette associated with an image.




imagetodib

void CopyDIBToClipboard(HWND hWnd, imgdes *image)
{
   int rcode=NO_ERROR;
   HGLOBAL hMem;
   UCHAR huge *dib;

   if(OpenClipboard(hWnd)) { // Open clipboard
      EmptyClipboard();
      // Create a new DIB to pass to the clipboard
      rcode = imagetodib(image, &dib);
      if(rcode == NO_ERROR) {
         // Get a handle to the new DIB
         hMem = GlobalPtrHandle(dib);
         // Unlock the handle to the DIB
         GlobalUnlock(hMem);
         // Pass the DIB to the clipboard
         SetClipboardData(CF_DIB, hMem);
         }
      CloseClipboard();
      }
   if(rcode != NO_ERROR)
      MessageBox(hWnd, "Error copying DIB to clipboard", 0,
         MB_OK);
}

This example creates a DIB from an image and passes the DIB to the clipboard.




isgrayscaleimage

No example


jpeggeterror

int loadAJpegFile(HWND hWnd, char *fname, imgdes *image)
{
   JpegData jdat;
   int rcode;

   // Get info on the file we're to load
   rcode = jpeginfo(fname, &jdat);
   if(rcode == NO_ERROR) { // Fill structure
      // Allocate space for an image
      rcode = allocimage(image, (int)jdat.width, (int)jdat.length, jdat.vbitcount);
      if(rcode == NO_ERROR) {
         // Load image
         rcode = loadjpg(fname, image);
         if(rcode == BAD_JPEG) {
            char szBuff[128];
            // Get extended error info
            int extRcode = jpeggeterror();
            wsprintf(szBuff, "Error in loading %s: extended error code %d", (LPSTR)fname, extRcode);
            MessageBox(hWnd, szBuff, 0, MB_OK);
            }
         freeimage(image); // Free image on error
         }
      }
   return(rcode);
}

This function reports extended error information when a JPEG file cannot be loaded.




jpeginfo

void jpegInfo(HWND hWnd, char *fname)
{
   JpegData jdat;             // Reserve space for structure 
   int rcode;
   char szBuff[80], *typstr;

   rcode = jpeginfo(fname, &jdat);
   if(rcode == BAD_OPN) {
      wsprintf(szBuff, "Could not find %s", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   else if(rcode == BAD_JPEG) {
      wsprintf(szBuff, "%s is not a JPEG JFIF file",
         (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   else {
      typstr = (jdat.comps == 1) ? "grayscale" : "color"; 
      wsprintf(szBuff, "%s is a %s JPEG image %d X %d pixels",
         (LPSTR)fname, (LPSTR)typstr, jdat.width, jdat.length);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
}

This example reads a JPEG file and displays the image size.




jpeginfoex

No Example

jpeginfofrombufferex

No example

jpegsetxyresolution

No example

kodalith

int trace(HWND hWnd, imgdes *image1, imgdes *image2)
{
   int rcode, rval, gval, bval;
   HCURSOR hSaveCursor;

   // Display hourglass cursor  
   hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
   rcode = calcavglevel(image1, &rval, &gval, &bval);
   if(rcode == NO_ERROR) { 
      if((rcode=kodalith(rval, image1, image2)) == NO_ERROR) {
         if((rcode=outline(image2, image2)) != NO_ERROR)
            MessageBox(hWnd,"Error at outline()", 0, MB_OK);
         } 
      else
         MessageBox(hWnd,"Error at kodalith()", 0, MB_OK);
      }
   else 
      MessageBox(hWnd,"Error at calcavglevel()", 0, MB_OK);
   SetCursor(hSaveCursor); // Restore cursor 
   return(rcode);
}

This example calculates a kodalith level then outlines the image.




limitlevel

int limit240(HWND hWnd, imgdes *image)
{
   int rcode, max=240;
   HCURSOR hSaveCursor;
   // Display hourglass cursor  
   hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
   rcode = limitlevel(max, image, image);
   if(rcode != NO_ERROR)
      MessageBox(hWnd,"Error at limitlevel()", 0, MB_OK);
   SetCursor(hSaveCursor); // Restore cursor 
   return(rcode);
}

This example limits the maximum intensity level in the image to 240.




loadbif

int load_bif(HWND hWnd, char *fname, imgdes *image)
{
   // BIF files must have predefined width and length
   int width=512, length=480; 
   OFSTRUCT of;
   int rcode=BAD_OPN; // Assume file does not exist
   
   // Make sure file exists
   if(OpenFile(fname, &of, OF_READ | OF_EXIST) == -1) {
      MessageBox(hWnd,"Error in opening file", 0, MB_OK);
      return(rcode);
      }
   // Allocate space for an 8-bit image 
   rcode = allocimage(image, width, length, 8);
   if(rcode != NO_ERROR) {
      MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
      return(rcode);
      }
    
   // Load image 
   rcode = loadbif(fname, image);
   if(rcode != NO_ERROR) // Free image on error
      freeimage(image);
   return(rcode);
} 

This example allocates space for and loads a BIF image.




loadbmp

int load_bmp(HWND hWnd, char *fname, imgdes *image)
{
   BITMAPINFOHEADER bminfo;
   int rcode, bppixel;

   // Get info on the file we're to load 
   rcode = bmpinfo(fname, &bminfo);
   if(rcode != NO_ERROR) { // Fill structure 
      MessageBox(hWnd,"Error in reading file", 0, MB_OK);
      return(rcode);
      }
   bppixel = bminfo.biBitCount;
   // Allocate space for an image 
   rcode = allocimage(image, (int)bminfo.biWidth, 
      (int)bminfo.biHeight, bppixel);
   if(rcode != NO_ERROR) {
      MessageBox(hWnd,"Not enough memory to load file", 
         0, MB_OK);
      return(rcode);
      }   // Load image 
   rcode = loadbmp(fname, image);
   if(rcode != NO_ERROR) // Free image on error
      freeimage(image);
   return(rcode);
} 

This example allocates space for and loads a BMP image.




loadbmppalette

int getBMPpal(HWND hWnd, char *fname, 
   // paltable must be sizeof(RGBQUAD) * (1 << biBitCount)
   RGBQUAD *paltable)
{
   int colors;
   char szBuff[80];

   colors = loadbmppalette(fname, paltable); // Load palette data 
   if(colors >= 0)   // Check range for error 
      wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
         colors);
   else
      wsprintf(szBuff, "Error on loading palette of %s",
         (LPSTR)fname);
   MessageBox(hWnd, szBuff, 0, MB_OK);   return(colors);
}

This example loads a BMP color palette into an array and if there are no errors, displays the number of palette colors loaded.




loadbmppalettefrombuffer




loadgif

int load_gif(HWND hWnd, char *fname, imgdes *image)
{
   GifData gdat;
   int rcode;

   // Get info on the file we're to load 
   rcode = gifinfo(fname, &gdat);
   if(rcode != NO_ERROR) { // Fill structure 
   MessageBox(hWnd,"Error in reading file", 0, MB_OK);
   return(rcode);
   }   // Allocate space for an 8-bit image 
    rcode = allocimage(image, gdat.width, gdat.length,
     gdat.vbitcount);
   if(rcode != NO_ERROR) {
   MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
   return(rcode);
   }
    
   // Load image 
   rcode = loadgif(fname, image);
   if(rcode != NO_ERROR) { 
   freeimage(image); // Free image on error
   MessageBox(hWnd, "Could not load file", 0, MB_OK);
   }
   return(rcode);
} 

This example allocates space for and loads a GIF image.




loadgifframe

// Load a GIF file
int load_animated_gif(LPTSTR fname, imgdes *image)
{
   GifData gifdat;   // Reserve space for struct
   int rcode;

   int totalFrames;
   GifGlobalData gdata;
   GifFrameData *fdatarray;  // Array of GifFrameData structures 

   HANDLE hmem;
   int size;
   int tempimage;

   // Loading all frames from a gif into a single vertical image

   rcode = gifframecount(fname, &totalFrames);  // Count the number of frames

   size = sizeof(GifFrameData);
   fdatarray = (GifFrameData *)calloc(totalFrames, size);

   rcode = gifinfoallframes(fname, &gdata, fdatarray, totalFrames); // Get all the frame info

   if(rcode == NO_ERROR) {
      int j;

      // Allocate an image buffer to hold all the frames
      if((rcode = allocimage(&tempimage, gdata.saveData.scrwidth, gdata.saveData.scrlength * totalFrames, fdatarray[0].vbitcount)) == NO_ERROR)
          zeroimage(gdata.saveData.bckColor, &tempimage);  // Set the background color

         // Load all frames
         for(j=0; j < totalFrames; j++) {
            tempimage.stx = fdatarray[j].saveData.startx ;
            tempimage.sty = j * gdata.saveData.scrlength + fdatarray[j].saveData.starty ;

            rcode = loadgifframe(fname, &tempimage, &gdata, &fdatarray[j]);
            }

        tempimage.stx = 0;
        tempimage.sty = 0;
        }

   // Replace original image with this new image of gif frames
   if(rcode == NO_ERROR || rcode == BAD_DATA) {
      freeimage(image);
      copyimgdes(&tempimage, image);
      rcode = NO_ERROR; // Set rcode to NO_ERROR if file contained invalid data
      }
   return(rcode);
}

This example loads all the frames from a multiframe GIF into a single image.




loadgifframefrombuffer




loadgiffrombuffer




loadgifpalette

int getGIFpal(HWND hWnd, char *fname, 
   RGBQUAD *paltable)  //paltable must be sizeof(RGBQUAD) * 256
{
   int colors;
   char szBuff[80];

   // Load palette data 
   colors = loadgifpalette(fname, paltable); 
   if(colors >= 0)   // Check range for error 
      wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
         colors);
   else
      wsprintf(szBuff, "Error on loading palette of %s", 
         (LPSTR)fname);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(colors);
}

This example loads a GIF color palette into an array and if there are no errors, displays the number of palette colors loaded.




loadgifframepalette

int getGIFframepal(HWND hWnd, char *fname, 
   RGBQUAD *paltable)  //paltable must be sizeof(RGBQUAD) * 256
{
   int colors;
   char szBuff[80];
   int framenumber;

   framenumber = 0;
   // Load palette data 
   colors = loadgifframepalette(fname, paltable, framenumber); 
   if(colors >= 0)   // Check range for error 
      wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
         colors);
   else
      wsprintf(szBuff, "Error on loading palette of %s", 
         (LPSTR)fname);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(colors);
}

This example loads the palette associated with the specified frame number.




loadgifframepalettefrombuffer




loadgifglobalpalette

int getGIFglobalpal(HWND hWnd, char *fname, 
   RGBQUAD *paltable)  //paltable must be sizeof(RGBQUAD) * 256
{
   int colors;
   char szBuff[80];

   // Load palette data 
   colors = loadgifglobalpalette(fname, paltable); 
   if(colors >= 0)   // Check range for error 
      wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
         colors);
   else
      wsprintf(szBuff, "Error on loading palette of %s", 
         (LPSTR)fname);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(colors);
}

This example loads a GIF global palette into an array and if there are no errors, displays the number of palette colors loaded.




loadgifglobalpalettefrombuffer




loadgifpalettefrombuffer




loadjpg

int load_jpg(HWND hWnd, char *fname, imgdes *image)
{
   JpegData jdat;
   int rcode;

   // Get info on the file we're to load 
   rcode = jpeginfo(fname, &jdat);
   if(rcode != NO_ERROR) { // Fill structure 
      MessageBox(hWnd, "Error in reading file", 0, MB_OK);
      return(rcode);
      }

   // Allocate space for an image
   rcode = allocimage(image, (int)jdat.width, (int)jdat.length,
      jdat.vbitcount);
   if(rcode != NO_ERROR) {
      MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
      return(rcode);
      }

   // Load image 
   rcode = loadjpg(fname, image);
   if(rcode != NO_ERROR) { 
      freeimage(image); // Free image on error
      MessageBox(hWnd, "Could not load file", 0, MB_OK);
      }
   return(rcode);
} 

This example allocates space for and loads a JPEG image.




loadjpgex

int loadJpgfilesfrombuffer(HWND hWnd, char *fname, imgdes *image)
   {
   #include <io.h>
   #define FILES_TO_LOAD dim(fileInfo)
   #define BAD_READ -87
   typedef struct { char *name; DWORD size; } FILE_INFO;
   
      JpegData jdat;      // Reserve space for struct
      int j, bytesRead, rcode = NO_ERROR;
      OFSTRUCT of_st;
      UCHAR huge *jpegbuff, huge *des;
      HFILE fhandle;
      DWORD memTotal;
      FILE_INFO fileInfo[] = {
         { "d:pic1.jpg", 0L },
         { "d:pic2.jpg", 0L },
         { "d:pic3.jpg", 0L },
         { "d:pic4.jpg", 0L },
         };
   
      // Load JPEG files into buffer
      memTotal = 0;
      for(j=0; j<FILES_TO_LOAD; j++) {
         if((fhandle = OpenFile(fileInfo[j].name, &of_st,
            OF_READ)) < 0)
            return(BAD_OPN);
         // Get filesize
   #if defined WIN32 || defined _WIN32
         fileInfo[j].size = GetFileSize((HANDLE)fhandle, NULL);
   #else
         fileInfo[j].size = _filelength(fhandle);
   #endif   
         memTotal += fileInfo[j].size;
         _lclose(fhandle);  // Close the file
         }      
   
      // Allocate memory to hold files
      jpegbuff = (UCHAR huge *)GlobalAllocPtr(GMEM_MOVEABLE,
         memTotal);
      if(jpegbuff == 0)
         return(BAD_MEM);   // Allocation failed!
         
      // Load JPEG files into memory
      des = jpegbuff;
      for(j=0; j<FILES_TO_LOAD; j++) { 
         if((fhandle = OpenFile(fileInfo[j].name, &of_st,
            OF_READ)) < 0)
            return(BAD_OPN);
         // For 16-bit Windows JPEG files must be less than 64Kb
         bytesRead = _lread(fhandle, des, 
            (unsigned)fileInfo[j].size);
         if(bytesRead <= 0)
            rcode = BAD_READ;
         _lclose(fhandle);   // Close the file
         des += fileInfo[j].size;
         }
   
      // Load the JPEG files from the buffer   
      des = jpegbuff;
      for(j=0; j<FILES_TO_LOAD; j++) {
         char szBuff[80];
         // Make sure file exists and get its dimensions
         rcode = jpeginfofrombuffer(des, &jdat);
         if(rcode == NO_ERROR) {
            // Release the current image buffer
            freeimage(image);
            // Try to allocate the new image buffer to the file
            // dimensions
            rcode = allocimage(image, jdat.width, jdat.length,
               jdat.vbitcount);
            if(rcode == NO_ERROR) {
               // Load the image
               rcode = loadjpgfrombuffer(des, image);
               if(rcode == NO_ERROR) {
                  // Display pic
                  ShowWindow(hWnd, SW_SHOWNORMAL);
                  UpdateWindow(hWnd);
                  wsprintf((LPSTR)szBuff, (LPSTR)"File %s
                     loaded",(LPSTR)fileInfo[j].name);
                  MessageBox(hWnd, szBuff, "Load JPEG from
                     Buffer", MB_OK);
                  }
               }   
            }
         des += fileInfo[j].size;
         }
      if(jpegbuff)
         GlobalFreePtr(jpegbuff); // Free any allocated memory
      return(rcode);
   }

This example loads four JPEG files from a buffer.




loadjpgfrombuffer




loadjpgfrombufferex




loadjpgthumbnail

int load_thumbnail(HWND hwnd, char *fname, imgdes *image)
{
   JpegDataEx jdatex;      // Reserve space for struct
   int rcode, width, length, bitcount;
   // Use embedded thumbnail if present
   BOOL createThumbNail = FALSE;
   int thumbSize = 64;  // Max width or length

   // Make sure file exists and get its dimensions
   if((rcode = jpeginfoex(fname, &jdatex)) == NO_ERROR) {

      // Load embedded thumbnail if thumbnail exists and
      //  createThumbNail flag is FALSE
      if(jdatex.thumbNail.hasThumbNail == TRUE &&
         createThumbNail == FALSE) 
         bitcount = jdatex.thumbNail.bitcount;
      else
         bitcount = jdatex.vbitcount;

      // Alloc a square image buffer 
      width = length = thumbSize;
      rcode = allocimage(image, width, length, bitcount);
      if(rcode == NO_ERROR) {
         zeroimage(0xff, image); // Set background to white
         // Load the image
         rcode = loadjpgthumbnail(fname, image, createThumbNail);
         }
      }
   if(rcode != NO_ERROR) { 
      freeimage(image); // Free image on error
      MessageBox(hWnd, "Could not load thumbnail", 0, MB_OK);
      }
   return(rcode);
}

This example allocates space for and loads a JPEG thumbnail image.




loadjpgthumbnailfrombuffer




loadpcx

int load_pcx(HWND hWnd, char *fname, imgdes *image)
{
   PcxData pdat;
   int rcode;

   // Get info on the file we're to load 
   rcode = pcxinfo(fname, &pdat);
   if(rcode != NO_ERROR) { // Fill structure 
      MessageBox(hWnd,"Error in reading file", 0, MB_OK);
      return(rcode);
      }

   // Allocate space for an image 
   rcode = allocimage(image, pdat.width, pdat.length,
      pdat.vbitcount);
   if(rcode != NO_ERROR) {
      MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
      return(rcode);
      }
    
   // Load image 
   rcode = loadpcx(fname, image);
   if(rcode != NO_ERROR) // Free image on error
      freeimage(image);
   return(rcode);
} 

This example allocates space for and loads a PCX image.




loadpcxpalette

int getPCXpal(HWND hWnd, char *fname, 
   RGBQUAD *paltable)   // paltable size -- see table above
{
   int colors;
   char szBuff[80];

   // Load palette data 
   colors = loadpcxpalette(fname, paltable); 
   if(colors >= 0)   // Check range for error 
      wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
         colors);
   else
      wsprintf(szBuff, "Error on loading palette of %s",
         (LPSTR)fname);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(colors);
}

This example loads a PCX color palette into an array and if there are no errors, displays the number of palette colors loaded.




loadpng

int loadAPng(HWND hWnd, char *fname, imgdes *image)
{
   PngData pdat;
   int rcode;

   // Get info on the file we're to load
   rcode = pnginfo(fname, &pdat);
   if(rcode != NO_ERROR) { // Fill structure
      MessageBox(hWnd,"Error in reading file", 0, MB_OK);
      return(rcode);
      }
   // Allocate space for the image
   rcode = allocimage(image, pdat.width, pdat.length, pdat.vbitcount);
   if(rcode != NO_ERROR) {
      MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
      return(rcode);
      }
   // Load image
   rcode = loadpng(fname, image);
   if(rcode != NO_ERROR) { 
      char szBuff[80];
      wsprintf(szBuff, "Could not load %s", fname);
      MessageBox(hWnd, szBuff, 0, MB_OK); 
      }
   freeimage(image); // Free image on error
   return(rcode);
} 

This example loads an image from a PNG file.




loadpngfrombuffer




loadpngpalette

int getPNGpal(HWND hWnd, char *fname, 
   RGBQUAD *paltab)  // paltab must be sizeof(RGBQUAD) * 256
{
   int colors;
   char szBuff[80];

   // Load palette data 
   colors = loadpngpalette(fname, paltab); 
   if(colors >= 0)   // Check range for error 
      wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname, colors);
   else
      wsprintf(szBuff, "Error on loading palette of %s", (LPSTR)fname);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(colors);
}

This example loads a PNG color palette into an array and if there are no errors, displays the number of palette colors loaded.




loadpngpalettefrombuffer




loadtga

int load_tga(HWND hWnd, char *fname, imgdes *image)
{
   TgaData tgdat;
   int rcode;

   // Get info on the file we're to load 
   rcode = tgainfo(fname, &tgdat);
   if(rcode != NO_ERROR) { // Fill structure 
      MessageBox(hWnd,"Error in reading file", 0, MB_OK);
      return(rcode);
      }
   // Allocate space for an image 
   rcode = allocimage(image, tgdat.width, tgdat.length,
      tgdat.vbitcount);
   if(rcode != NO_ERROR) {
      MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK);
      return(rcode);
      }
   rcode = loadtga(fname, image);
   if(rcode != NO_ERROR) // Free image on error
      freeimage(image);
   return(rcode);
} 

This example allocates space for and loads a Targa true color file.




loadtgapalette

int getTGApal(HWND hWnd, char *fname, 
   RGBQUAD *paltable)  //paltable must be sizeof(RGBQUAD) * 256
{
   int colors;
   char szBuff[80];

   // Load palette data 
   colors = loadtgapalette(fname, paltable); 
   if(colors >= 0)   // Check range for error 
      wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
         colors);
   else
      wsprintf(szBuff, "Error on loading palette of %s",
         (LPSTR)fname);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(colors);
}

This example loads a Targa color palette into an array and if there are no errors, displays the number of palette colors loaded.




loadtgawithalpha




loadtif

int load_tif(HWND hWnd, char *fname, imgdes *image)
{
   TiffData tdat;
   int rcode;

   // Get info on the file we're to load 
   rcode = tiffinfo(fname, &tdat);
   if(rcode != NO_ERROR) { // Fill structure 
      MessageBox(hWnd,"Error in reading file", 0, MB_OK);
      return(rcode);
      }

   // Allocate space for an image 
   rcode = allocimage(image, tdat.width, tdat.length,
       tdat.vbitcount);
   if(rcode != NO_ERROR) {
      MessageBox(hWnd,"Not enough memory to load file", 0, MB_OK); 
           return(rcode);
      }
   rcode = loadtif(fname, image);
   if(rcode != NO_ERROR) // Free image on error
      freeimage(image);
   return(rcode);
} 

This example allocates space for and loads a TIFF image.




loadtiffrombuffer




loadtifpage

int loadMultiTiff(HWND hWnd, char *filename, imgdes *image, 
   int pageToLoad)
{
// Returns no. of elements
#define dim(x) (sizeof(x) / sizeof(x[0]))   

   TiffData tdat;     // Reserve space for struct
   int indx, rcode;
   int pageArray[16]; // Allow room for 16 pages
   int totalPages;
   BOOL pageFound;

   // Fill the page array
   rcode = tiffgetpageinfo(filename, &totalPages, pageArray,
      dim(pageArray));
   if(rcode == NO_ERROR) {
      pageFound = FALSE; // Assume page to load is NOT in the file
      // Make sure page to load is in the file
     for(j=0; j<totalPages; j++) {
        if(pageToLoad == pageArray[j]) {
           pageFound = TRUE;
           break;
           }
        }
     // Handle "page not found" error
     if(pageFound == FALSE) {
        char szBuff[80];
        wsprintf(szBuff, "Page %d not found in %s", pageToLoad,
           (LPSTR)fname);
        MessageBox(hWnd, szBuff, "Error!", MB_OK);
        }
     else { // Found page to load in TIFF file, load it
        // Get the dimensions of the page to load
         if((rcode = tiffinfopage(filename, &tdat, pageToLoad)) ==
           NO_ERROR) {
           // Allocate an image buffer based on the file dimensions
             if((rcode = allocimage(image, tdat.width, tdat.length,
                tdat.vbitcount)) == NO_ERROR)
                // Load the image
                rcode = loadtifpage(fname, image, pageToLoad);
           }
        }
   return(rcode);
}

This example loads a specific page (image) from a single or multipage TIFF file.




loadtifpagebyindex




loadtifpalette

int getTIFpal(HWND hWnd, char *fname, 
   RGBQUAD *paltable)  //paltable must be sizeof(RGBQUAD) * 256
{
   int colors;
   char szBuff[80];

   // Load palette data 
   colors = loadtifpalette(fname, paltable); 
   if(colors >= 0)   // Check range for error 
      wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
         colors);
   else
      wsprintf(szBuff, "Error on loading palette of %s",
         (LPSTR)fname);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(colors);
}

This example loads a TIFF color palette into an array and if there are no errors, displays the number of palette colors loaded.




loadtifpalettefrombuffer




loadtifpalettepage

int getTIFpalpage(HWND hWnd, char *fname, 
   RGBQUAD *paltable)  //paltable must be sizeof(RGBQUAD) * 256
{
   int colors, pageno=2;
   char szBuff[80];
   int pageno;

   // Load palette data 
   colors = loadtifpalettepage(fname, paltable, pageno); 
   if(colors >= 0)   // Check range for error 
      wsprintf(szBuff, "%s contains %d colors", (LPSTR)fname,
         colors);
   else
      wsprintf(szBuff, "Error on loading palette from page 2 of %s",
         (LPSTR)fname);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(colors);
}

This example loads a TIFF color palette into an array and if there are no errors, displays the number of palette colors loaded.




loadtifpalettepagebyindex




loadtifwithalpha




matchcolorimage




matchcolorimageex

// Force three images to use same palette. Images must be 8-bit!
int matchupEx(imgdes *farm, imgdes *city, imgdes *lake)
{
   int rcode;
   imgdes timage;
   int colmatchmode = CR_TDSNODIFF;

   // Force city and lake to use farm palette
   // Match city and lake to farm
   copyimgdes(city, &timage);
   timage.palette = farm->palette;
   timage.colors = farm->colors;
   // Force city to use farm's palette
   rcode = matchcolorimageex(city, &timage, colmatchmode);
   if(rcode == NO_ERROR) {
      copyimagepalette(farm, city);  // Replace city's palette
      city->colors = farm->colors;

      copyimgdes(lake, &timage);
      timage.palette = farm->palette;
      timage.colors = farm->colors;
      // Force city to use farm's palette
      rcode = matchcolorimageex(lake, &timage, colmatchmode);
      copyimagepalette(farm, lake);  // Replace lake's palette
      lake->colors = farm->colors;
      }
   return(rcode);
}

This example forces two images to use the palette of a third image.




matchcolorimageex

int combineImagesEx(HWND hWnd, imgdes *simage1, imgdes *simage2)
{
   int imgnum, rcode;
   imgdes timage, *image;
   int colmatchmode= CR_OCTREEDIFF;

   image = simage1; // Setup for first image 
   for(imgnum=0; imgnum<2; imgnum++) {
      // Allocate 8-bit buffer for the converted image 
      rcode = allocimage(&timage, (int)image->bmh->biWidth, 
      (int)image->bmh->biHeight, 8);
      if(rcode == NO_ERROR) {
         rainbowpalette(&timage);   // Use a standard palette 
         // Match the image to the palette
         rcode = matchcolorimageex(image, &timage, colmatchmode);
         if(rcode == NO_ERROR) {
            // Replace image with timage, free source image 
            freeimage(image);
            copyimgdes(&timage, image);
            }
         else { // matchcolorimageex() failed, release timage 
            freeimage(&timage);  
            MessageBox(hWnd, "Error in matching color palette",
               0,MB_OK);
            break;
            }
         }
      image = simage2; // Setup for second image 
      }
   return(rcode);
}

This example matches two 24- or 8-bit images to a single rainbow palette and replaces the original images.




matrixconv

int detect_horiz(HWND hWnd, imgdes *image)
{
   static char dethoriz[] = {1, 1, 1, 0, 0, 0, -1, -1, -1, 1 };
   int rcode;
   
   if((rcode=matrixconv(dethoriz, image, image)) != NO_ERROR)
      MessageBox(hWnd,"Error at matrixconv()", 0, MB_OK);
   return(rcode);
}

This example emphasizes the horizontal lines in an image.




matrixconvex

int detect_horiz2(HWND hWnd, imgdes *image)
{
   static char dethoriz[] = {1, 1, 1, 0, 0, 0, -1, -1, -1};
   int divsr = 1;
   int rcode;
   
   rcode = matrixconvex(3, dethoriz, divsr, image, image);
   if(rcode != NO_ERROR)
      MessageBox(hWnd,"Error at matrixconvex()", 0, MB_OK);
   return(rcode);
}

This example emphasizes the horizontal lines in an image.




medianfilter

int watercolor(HWND hWnd, imgdes *image)
{
   int rcode;
   
   rcode = medianfilter(3, image, image);
   if(rcode != NO_ERROR)
      MessageBox(hWnd,"Error at matrixconvex()", 0, MB_OK);
   else {
      medianfilter(5, image, image);
      medianfilter(7, image, image);
      sharpen(image, image);
      }
   return(rcode);
}

This example creates a watercolor painting effect in an image.




mirrorimage

int mirror(HWND hWnd, char *fname, imgdes *image)
{
   int rcode;
   char szBuff[80];

   if((rcode=loadtif(fname, image)) == NO_ERROR) {
      if((rcode=mirrorimage(image, image)) == NO_ERROR) {
         if((rcode=savetif(fname, image, 0)) != NO_ERROR) {
            wsprintf(szBuff, "Error in saving %s", (LPSTR)fname);
            MessageBox(hWnd, szBuff, 0, MB_OK);
            }
         }
      else  
         MessageBox(hWnd,"Error at mirrorimage()", 0, MB_OK);
      }
   else {
      wsprintf(szBuff, "Error in loading %s", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   return(rcode);
}

This example loads an image, mirrors it for creating an iron-on transfer, and saves it.




multiplyimage




negative

int negtrace(HWND hWnd, imgdes *image1, imgdes *image2)
{
   int rcode;
   HCURSOR hSaveCursor;

   // Display hourglass cursor  
   hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));
   if((rcode=kodalith(128, image1, image2)) == NO_ERROR) {
      if((rcode=outline(image2, image2)) == NO_ERROR) {
         rcode = negative(image2, image2);
         if(rcode != NO_ERROR)
            MessageBox(hWnd,"Error at negative()", 0, MB_OK);
         }
      else
         MessageBox(hWnd,"Error at outline()", 0, MB_OK);
      }
   else
      MessageBox(hWnd,"Error at kodalith()", 0, MB_OK);
   SetCursor(hSaveCursor); // Restore cursor 
   return(rcode);
}

This example makes a new image that appears to be the photographic negative of the original image.




orimage

int or2(HWND hWnd, imgdes *image1, imgdes *image2, imgdes
   *image3)
{
   int rcode;

   if((rcode=blur(image1, image2)) == NO_ERROR) {
      if((rcode=orimage(image1, image2, image3)) != NO_ERROR)
         MessageBox(hWnd,"Error in ORing images", 0, MB_OK);
      }
   else
      MessageBox(hWnd,"Error in blurring image", 0, MB_OK);
   return(rcode);
}

This example smooths image1, ORs the original image with the smoothed image, and places the result in image3.




outline

int trace(HWND hWnd, imgdes *image1, imgdes *image2)
{
   int rcode, rval, gval, bval;
   HCURSOR hSaveCursor;

   // Display hourglass cursor  
   hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));

   rcode = calcavglevel(image1, &rval, &gval, &bval);
   if(rcode == NO_ERROR) {
      if((rcode=kodalith(rval, image1, image2)) == NO_ERROR) {
         if((rcode=outline(image2, image2)) != NO_ERROR)
            MessageBox(hWnd,"Error at outline()", 0, MB_OK);
         } 
      else
         MessageBox(hWnd,"Error at kodalith()", 0, MB_OK);
      }
   else 
      MessageBox(hWnd,"Error at calcavglevel()", 0, MB_OK);
   SetCursor(hSaveCursor); // Restore cursor 
   return(rcode);
}

This example calculates a level for a kodalith then outlines the image.




pcxinfo




pixelcount

int pincrease(HWND hWnd, imgdes *image)
{
   int rcode, area_wide, area_long, min=230, max=255;
   long pels, redcnt, grncnt, blucnt, sum;

   // Calculate pixels in image area of interest 
   area_wide = image->endx - image->stx + 1;   
   area_long = image->endy - image->sty + 1;    
   pels = area_wide * (long)area_long;           
   for(;;) {
      if((rcode=pixelcount(min, max, &redcnt, &grncnt, &blucnt,
         image)) != NO_ERROR) {
         MessageBox(hWnd,"Error in counting pixels", 0, MB_OK);
         break;
         }
      sum = redcnt;
      if(image->bmh->biBitCount == 24) 
         // Adjust pixelcount for 3 planes

         sum = (redcnt + grncnt + blucnt) / 3;
      // If pixels between min and max < 10% pels, brighten 
      if(sum >= pels / 10) 
         break;    // We are done!
      if((rcode=changebright(10, image, image)) != NO_ERROR) {
         MessageBox(hWnd,"Error in changing brightness", 0,
            MB_OK);
         break;
         }
      }
   return(rcode);
}

This example increases the brightness until the range 230 to 255 contains at least 10 percent of the total pixels in the image area.




pixellize

int pix8(HWND hWnd, imgdes *image)
{
   int rcode, pixfactor=8;

   rcode = pixellize(pixfactor, image, image);   
   if(rcode == NO_ERROR)
      MessageBox(hWnd,"Error at pixellize()", 0, MB_OK);
   return(rcode);
}

This example pixellizes an image area using a pixellation factor of 8.




pnggeterror

int loadAPngFile(HWND hWnd, char *fname, imgdes *image)
{
   PngData pdat;
   int rcode;

   // Get info on the file we're to load
   rcode = pnginfo(fname, &pdat);
   if(rcode == NO_ERROR) { // Fill structure
      // Allocate space for an image
      rcode = allocimage(image, (int)pdat.width, (int)pdat.length, pdat.vbitcount);
      if(rcode == NO_ERROR) {
         // Load image
         rcode = loadpng(fname, image);
         if(rcode == BAD_PNG) {
            char szBuff[128];
            // Get extended error info
            int extRcode = pnggeterror();
            wsprintf(szBuff, "Error in loading %s: extended error code %d", (LPSTR)fname, extRcode);
            MessageBox(hWnd, szBuff, 0, MB_OK);
            }
         freeimage(image); // Free image on error
         }
      }
   return(rcode);
}

This function reports extended error information when a PNG file cannot be loaded.




pnggetxyresolution




pnginfo

void pngsize(HWND hWnd, char *fname)
{
   PngData pdat;             // Reserve space for structure 
   int rcode;
   char szBuff[80];

   rcode = pnginfo(fname, &pdat);
   if(rcode == BAD_OPN) {
      wsprintf(szBuff, "Could not find %s", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   else if(rcode == BAD_PNG) {
      wsprintf(szBuff, "%s is not a PNG file", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   else {
      wsprintf(szBuff, 
         "%s image dimensions: Width=%d, Length=%d",
         (LPSTR)fname, pdat.width, pdat.length);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
}

This example reads a PNG file and prints the image size.




pnginfofrombuffer




pngsetxyresolution




printimage

#define PRTDEFAULT  0// in VICDEFS.H
#define PRTHALFTONE 1
#define PRTSCATTER  2

// Global variables
int CancelPrt;    // Cancel printing flag
HWND hDlgPrt;   // "Cancel printing" dialog box handle
imgdes Image;     // Image to print

// Display current band number in "cancel printing" dialog box.
   Returns state of cancel printing flag (Cancel if TRUE).

int _export FAR PASCAL DisplayProgress(int bandno)
{
#define IDC_TEXT 0x200
   MSG msg;
   char szBuff[64];

   // Display progress in cancel printing dialog box
   if(hDlgPrt) {   // If dialog exists...
      wsprintf(szBuff, "Imaging band number %d", bandno);
      SetDlgItemText(hDlgPrt, IDC_TEXT, szBuff);
      }
   // Allow other apps and cancel print dialog to process messages
   while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
      if(!hDlgPrt || !IsDialogMessage(hDlgPrt, &msg)) {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
         }
      }
   return(CancelPrt); // Return state of "cancel printing" flag
}

// Dialog proc for "cancel printing" dialog box
int _export FAR PASCAL CancelPrtProc(HWND hDlg, WORD message, WORD
wParam, LONG lParam)
{
   if(message == WM_COMMAND && wParam == IDCANCEL) {
      CancelPrt = TRUE; // Cancel printing
      return(TRUE);
      }
   return(FALSE);
}
// "Print an image area" command selected from menu
LONG DoPrint(HWND hWnd, WORD msg, WORD wParam, LONG lParam)
{
#define IDD_PRTCANCEL 0x210
   int xpos, ypos, rcode, frame = 1;
   DLGPROC lpfnDispProg;  // Function to display current band
   DLGPROC lpfnPrtProc;   // Dialog to cancel printing
   HINSTANCE hInst = GetWindowInstance(hWnd);
    HDC hPrn;      // Printer Device Context
   int prtmode = PRTHALFTONE; // Use halftone print mode
   RECT prtrc;
   
   // Get printer DC
   if((hPrn = GetPrinterDC()) == NULL)
      rcode = PRT_ERR;
   else {
      // Disable main window to prevent closing
      EnableWindow(hWnd, FALSE);
      CancelPrt = 0;    // Clear cancel printing flag

      // Create a "cancel printing" dialog box
      lpfnPrtProc = (DLGPROC)MakeProcInstance(
         (FARPROC)CancelPrtProc,hInst);
      hDlgPrt = CreateDialog(hInst,MAKEINTRESOURCE(IDD_PRTCANCEL),
         hWnd, (DLGPROC)lpfnPrtProc);

      // Create procedure-instance pointer to DisplayProgress()
      // printimage calls that function to display current band
         lpfnDispProg = (DLGPROC)MakeProcInstance(
            (FARPROC)DisplayProgress, hInst);

      // Area to print: 3 inches x 5 inches, 2.5" down and in 
      xpos = 2500; ypos = 2500;
      SetRect(&prtrc, xpos, ypos, xpos + 2999, ypos + 4999);

      // Print the image
      rcode = printimage(hWnd, hPrn, prtmode, &Image, &prtrc,
         frame, lpfnDispProg);

      FreeProcInstance(lpfnDispProg);
      EnableWindow(hWnd, TRUE); // Re-enable main window
      DestroyWindow(hDlgPrt);   // Delete "cancel printing" dialog
      hDlgPrt = 0;
      FreeProcInstance(lpfnPrtProc);
      DeleteDC(hPrn);           // Delete printer DC
      }
   if(rcode != NO_ERROR) 
      MessageBox(hWnd, "Error in printing image", 0, MB_OK);
   return(0L);
}

// Read WIN.INI for default printer and create a DC. 
// Returns a handle to the DC or 0 if unsuccessful.

HDC GetPrinterDC(void)
{
   char szPrinter[80];
   char *szDevice, *szDriver, *szOutput;

   GetProfileString("windows", "device", "", szPrinter,
      sizeof(szPrinter));

   if((szDevice = strtok(szPrinter, ",")) &&
      (szDriver = strtok(0, ", ")) &&
      (szOutput = strtok(0, ", ")))
      return(CreateDC(szDriver, szDevice, szOutput, 0));

   return(0);
}

This example prints a 3 x 5 inch image in the center of the pageand displays a dialog box that reports printing progress andallows the user to cancel printing.




printimageenddoc

printimagenoeject

printimagestartdoc

// Functions GetPrinterDC(), CancelPrtProc(), and 
// DisplayProgress() are defined in printimage() example
void DoPrintTwoImages(HWND hWnd)
{
#define IDD_PRTCANCEL 0x210
  int xpos, ypos, rcode, frame = 1;
  HINSTANCE hInst = GetWindowInstance(hWnd);
  HDC hPrn;       // Printer Device Context
  int prtmode = PRTHALFTONE; // Use halftone print mode
  RECT prtrc;
  char szBuff[256];
  BOOL ejectPage;   // Eject the page if TRUE
   
  // Get printer DC
  if((hPrn = GetPrinterDC()) == NULL)
     rcode = PRT_ERR;
  else {
     // Disable main window to prevent closing
     EnableWindow(hWnd, FALSE);
     CancelPrt = FALSE; // Clear cancel printing flag
     // Create a "cancel printing" dialog box
     hDlgPrt = CreateDialog(hInst,
        MAKEINTRESOURCE(IDD_PRTCANCEL),hWnd,
        (DLGPROC)CancelPrtProc);

     // Print 3 x 5 inch image 0.5 inch from left, xpos = 500;
    // ypos = 2500; 2.5 inches from top 
    SetRect(&prtrc, xpos, ypos, xpos + 2999, ypos + 4999);

    // Set doc name for print manager
    GetWindowText(hWnd, szBuff, sizeof(szBuff));

    // Initialize for multi-image printing
    rcode = printimagestartdoc(hPrn, szBuff); 
    if(rcode == NO_ERROR) {

       // Print the first image
       rcode = printimagenoeject(hWnd, hPrn, prtmode, &Image,
          &prtrc, frame, (DLGPROC)DisplayProgress);
       if(CancelPrt == FALSE && rcode == NO_ERROR) {
       // Add some text to the page
       SetTextAlign(hPrn, TA_UPDATECP);
       MoveTo(hPrn, 1 * 300, 2 * 300);
       TextOut(hPrn, 0, 0, "This is a test", 14);
       // Print 3 x 5 inch image 4.0 inches from left,
       xpos = 4000; ypos = 2500; // 2.5 inches from top
       SetRect(&prtrc, xpos, ypos, xpos + 2999, ypos + 4999);
       // Print the second image
       rcode = printimagenoeject(hWnd, hPrn, prtmode,
          &Image,&prtrc, frame, (DLGPROC)DisplayPrtProg);
       }
    // Eject the page if the user didn't abort & no errors
    ejectPage = CancelPrt == FALSE && rcode == NO_ERROR;
    printimageenddoc(hPrn, ejectPage);
    }
  EnableWindow(hWnd, TRUE); // Re-enable main window
  DestroyWindow(hDlgPrt);   // Delete "cancel printing" dialog
  hDlgPrt = 0;
  DeleteDC(hPrn);           // Delete printer DC
  }
if(rcode != NO_ERROR) 
  MessageBox(hWnd, "Error in printing image", 0, MB_OK);
}

This example prints two 3 x 5 inch images and some text in the center of the page and displays a dialog box that reports printing progress and allows the user to cancel printing.





rainbowpalette

int rainbowview(HWND hWnd, imgdes *srcimg)
{
   int rcode, rows, cols;
   HDC hDC;
   HPALETTE hpal;
   imgdes resimg;
   PAINTSTRUCT ps;

   rows = srcimg->endy - srcimg->sty + 1;
   cols = srcimg->endx - srcimg->stx + 1;

   // Allocate temporary 8-bit image for viewing
   rcode = allocimage(&resimg, cols, rows, 8);

   if(rcode == NO_ERROR) {
      // Create rainbow palette in result image
      rainbowpalette(&resimg);                 
      // Force 24-bit image to use rainbow palette
      rcode = matchcolorimage(srcimg, &resimg);
      if(rcode != NO_ERROR)
         MessageBox(hWnd, 
         "Could not convert RGB to 8-bit image", 0, MB_OK);
      else {
         hDC = BeginPaint(hWnd, &ps);
         // Display the image at (0,0) 
         rcode = viewimageex(hWnd, hDC, &hpal, 0, 0, &resimg, 0,
            0, VIEWDITHER);   
         EndPaint(hWnd, &ps);
         if(rcode != NO_ERROR)
            MessageBox(hWnd, "Error displaying image", 0, MB_OK);
         }
      DeleteObject(hpal);            
      // Release the temporary 8-bit image
      freeimage(&resimg);
      }
   return(rcode);
}  

This example converts an RGB image to an 8-bit palette color image with a rainbow palette for display.




recttoimagearea




reduceimagecolors

int makea16colorimage(HWND hWnd, imgdes *srcimg, imgdes *resimg)
{
   int rcode, rows, cols;

   cols = srcimg->endx - srcimg->stx + 1;
   rows = srcimg->endy - srcimg->sty + 1;
   // Allocate space for the 16-color image 
   rcode = allocimage(resimg, cols, rows, 8);
   if(rcode != NO_ERROR) {
      MessageBox(hWnd,
         "Not enough memory to create 16-color image", 0, MB_OK);
      return(rcode);
      }

   resimg->colors = 16;  // Reduce palette colors to 16
   rcode = reduceimagecolors(srcimg, resimg);
   if(rcode !=  NO_ERROR) {
      freeimage(resimg);      
      MessageBox(hWnd,"Error in creating 16-color image", 0,
         MB_OK);
      }
   return(rcode);
}

This example creates a 16-color image for display on 16-color display adapters.




removenoise

int RemoveRandomNoise(HWND hWnd, imgdes *image)
{
   int rcode;

   if((rcode=removenoise(image, image)) != NO_ERROR) 
      MessageBox(hWnd,"Error at removenoise", 0, MB_OK);
   return(rcode);
}

This example removes random noise from the image area.




copyimgdes



resize

void ResizeImage(HWND hWnd, imgdes *image)
{
   imgdes timage;
   int dx, dy, rcode, pct = 50; // 50% reduction

   // Allocate space for the new DIB
   dx = (int)(((long)(image->endx - image->stx + 1)) * pct / 100);
   dy = (int)(((long)(image->endy - image->sty + 1)) * pct / 100);
   if((rcode = allocimage(&timage, dx, dy,
      image->bmh->biBitCount)) == NO_ERROR) {
      // Resize Image into timage
      if((rcode = resize(image, &timage)) == NO_ERROR) {
         // Success, free source image
         freeimage(image);
         // Assign timage to image
         copyimgdes(&timage, image);
         }
      else // Error in resizing image, release timage memory
         freeimage(&timage);
      }
   if(rcode != NO_ERROR)
      MessageBox(hWnd, "Error in resizing image", 0, MB_OK);
}

This example resizes an image area and replaces the original image with the new image.





resizeex

void ResizeImageByInterp(HWND hWnd, imgdes *image)
{
   imgdes timage;
   int dx, dy, rcode, pct = 50; // 50% reduction
   int mode = RESIZEBILINEAR; // Bilinear interpolation

   // Allocate space for the new DIB
   dx = (int)(((long)(image->endx - image->stx + 1)) * pct / 100);
   dy = (int)(((long)(image->endy - image->sty + 1)) * pct / 100);
   if((rcode = allocimage(&timage, dx, dy,
      image->bmh->biBitCount)) == NO_ERROR) {
      // Resize Image into timage
      if((rcode = resizeex(image, &timage, mode)) == NO_ERROR) {
         // Success, free source image
         freeimage(image);
         // Assign timage to image
         copyimgdes(&timage, image);
         }
      else // Error in resizing image, release timage memory
         freeimage(&timage);
      }
   if(rcode != NO_ERROR)
      MessageBox(hWnd, "Error at resizeex()", 0, MB_OK);
}

This example resizes an image area using interpolation and replaces the original image with the new image.




rgb2hsv

void rgb_to_hsv(int colors, // Number of RGBQUADs to convert
   imgdes *image, HSVTRIPLE *hsvtab)
{
   rgb2hsv(image->palette, hsvtab, colors);
}

This example converts an RGB palette associated with an image to an HSV table.




rotate

#include math.h // for sin and cos functions
int rotate_any_angle(imgdes *image)
{
   imgdes timage;
   int rcode, rotwidth, rotlength;
   double angle = 37.21;
   double cols, rows, costheta, sintheta;
  
   cols = (double)CALC_WIDTH(image); // VICDEFS.H macros
   rows = (double)CALC_HEIGHT(image);
   costheta = fabs(cos(angle));  sintheta = fabs(sin(angle));
    rotwidth = (int)(costheta * cols + sintheta * rows);
   rotlength = (int)(sintheta * cols + costheta * rows);
   // Allocate buffer large enough to hold entire rotated image area
   rcode = allocimage(&timage, rotwidth, rotlength, 
      image->bmh->biBitCount);

   if(rcode == NO_ERROR) { 
      // Rotate image area
      rcode = rotate(angle, image, &timage);
      if(rcode == NO_ERROR) {
         // Copy palette data into rotated image
         copyimgpalette(image, &timage);
         freeimage(image);
         // Replace original image with rotated image
         copyimgdes(&timage, image);
         }
      else
         freeimage(&timage);  // Release memory if error
      }
   return(rcode);
}

This example rotates an image 37.21 degrees and modifies the image descriptor to describe the new rotated image.




rotate90

int rotate_90(imgdes *image)
{
#define CW  0
#define CCW 1
   imgdes timage;
   int rcode, rotwidth, rotlength, rotflag=CW;

   rotlength = image->endx - image->stx + 1;
   rotwidth  = image->endy - image->sty + 1;
   copyimgdes(image, &timage);
   rcode = allocimage(&timage, rotwidth, rotlength, 
      image->bmh->biBitCount);

   if(rcode == NO_ERROR) {
      rcode = rotate90(rotflag, image, &timage);
      if(rcode == NO_ERROR) {
         // Copy palette data into rotated image
         copyimgpalette(image, &timage);
         freeimage(image);
         // Replace original image with rotated image
         copyimgdes(&timage, image);
         }
      else
         freeimage(&timage);  // Release memory if error
      }
   return(rcode);
}

This example rotates an image 90 degrees clockwise and modifies the image descriptor to describe the new rotated image.




savebif

int save_bif(HWND hWnd, char *fname, imgdes *image)
{
   int rcode;
   char szBuff[80];

   rcode = savebif(fname, image);
   if(rcode == BAD_DSK)   
      wsprintf(szBuff, "Could not save %s, disk full",
         (LPSTR)fname);
   else if(rcode == BAD_CRT)
      wsprintf(szBuff, "Could not create %s", (LPSTR)fname);
   else if(rcode == NO_ERROR)
      wsprintf(szBuff, "%s saved as %d x %d BIF file",
         (LPSTR)fname,
         (int)image->bmh->biWidth, (int)image->bmh->biHeight);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(rcode);
}

This example saves an image area as a binary image file.




savebmp

int save_bmp(HWND hWnd, char *fname, imgdes *image)
{
   int rcode, comp=0;  // Save as uncompressed
   char szBuff[80];

   rcode = savebmp(fname, image, comp);
   if(rcode != NO_ERROR) {
      wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   return(rcode);
}

This example saves an image as an uncompressed BMP file.





savebmptobuffer




saveeps

int save_eps(HWND hWnd, char *fname, imgdes *image)
{
   int rcode;
   char szBuff[80];

   rcode = saveeps(fname, image);
   if(rcode == BAD_DSK)   
      wsprintf(szBuff, "Could not save %s, disk full",
         (LPSTR)fname);
   else if(rcode == BAD_CRT)
      wsprintf(szBuff, "Could not create %s", (LPSTR)fname);
   else if(rcode == NO_ERROR)
      wsprintf(szBuff, "%s saved as %d x %d EPS file",
         (LPSTR)fname, (int)image->bmh->biWidth, 
         (int)image->bmh->biHeight);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(rcode);
}

This example saves an image area as an Encapsulated Postscript file.





savegif

int save_gif(HWND hWnd, char *fname, imgdes *image)
{
   int rcode;
   char szBuff[80];

   rcode = histoequalize(image, image);
   if(rcode != NO_ERROR) 
      wsprintf(szBuff, "Error in brightening image");
   else {
      rcode = savegif(fname, image);
      if(rcode != NO_ERROR) 
         wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
      }
   if(rcode != NO_ERROR)
      MessageBox(hWnd, szBuff, 0, MB_OK);
   return(rcode);
}

This example brightens an image and saves it as a GIF file.




savegifex

int saveGifEx(HWND hWnd, char *fname, imgdes *image)
{
#define VINTERLACE   1 // Defined in VICDEFS.H
#define VTRANSPARENT 2
#define VWRITE4BIT   4
   int rcode;
   // Write a transparent, interlaced GIF
   int saveMode = VINTERLACE | VTRANSPARENT;
   int transColor = 10; // Transparent color is 10

   // Write a 4-bit GIF if palette colors are 16 or less
   if(image->colors <= 16)
   saveMode |= VWRITE4BIT;

   rcode = savegifex(fname, imgptr, saveMode, trasnColor);
   if(rcode != NO_ERROR) {
   char szBuff[80];
   wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   }
   return(rcode);
}

This example saves an image area as a transparent, interlaced, 4- or 8-bit GIF file.





savegifframe

int findwhite(imgdes *srcimg) // Helper function to find white palette entry
{
   int j;
   int r, g, b;
   int maxwhite = 0;
   int maxwhiteindex = -1;

   for(j = 0; j <= srcimg->colors; j++) {
      r = srcimg->palette[j].rgbRed;
      g = srcimg->palette[j].rgbGreen;
      b = srcimg->palette[j].rgbBlue;
      if(r == g && r == b)
         if (r > maxwhite) {
            maxwhiteindex = j;
            maxwhite = r;
            }
      }

   return maxwhiteindex;
}

// Make an animated gif of a growing image
int makegrowingGIF(int frames, imgdes *srcimg)
{
   int rcode = NO_ERROR;
   int cols, rows;
   int j;
   int wd, ht;
   imgdes desimg;
   int foundwhite;
   GifGlobalSaveData gdata;
   GifFrameSaveData fdata;

   if(srcimg->bmh->biBitCount != 8)
      return(BAD_BPP);
   
   cols = CALC_WIDTH(srcimg);
   rows = CALC_HEIGHT(srcimg);
   foundwhite = findwhite(srcimg);

   // GIF global data used by savegifframe(), etc.
   gdata.scrwidth = cols;
   gdata.scrlength = rows;
   gdata.hasColorMap = TRUE; // Global color table is present!
   gdata.bckColor = foundwhite;  // Color index of screen backgnd
   gdata.loop = 1000;    // Number of iterations

   fdata.startx = 0;
   fdata.starty = 0; // X,Y pixel position with respect to scrwidth, scrlength
   fdata.hasColorMap = FALSE; // Local color table present?
   fdata.delay = 1;        // 100ths of a second to display frame
   fdata.transColor = -1;        // Transparent color index, -1 => none
   fdata.removeBy = 0;          // How graphic is to be treated after display
   fdata.waitForUserInput = FALSE; // If true, expect user input

   wd = cols/frames/2;
   ht = rows/frames/2;
   rcode = allocimage(&desimg, cols, rows, 8);
   copyimagepalette(srcimg, &desimg);
   zeroimage(foundwhite, &desimg);

   // First frame, plain white
   rcode = savegifframe("growing.gif", &desimg, &gdata, &fdata, GIFLZWCOMP );   // or  GIFNOCOMP 

   for(j = frames-1; j >= 0; j--) {
      // GIF frame data used by savegifframe(), etc.
      fdata.startx = wd*j;
      fdata.starty = ht*j; // X,Y pixel position with respect to scrwidth, scrlength
      fdata.removeBy = 2;          // How graphic is to be treated after display
         //NOTHING    0  The image is left unremoved
         //ASIS       1  The image is left unremoved
         //BACKGROUND 2  The image is replaced by the background
         //PREVIOUS   3  The image is replaced by the previous image

      // Create a growing image 
      setimagearea(&desimg, fdata.startx, fdata.starty, cols-fdata.startx-1, rows-fdata.starty-1);
      resizeex(srcimg, &desimg, RESIZEFAST);  // 1 = RESAMPLEBILINEAR
      rcode = savegifframe("growing.gif", &desimg, &gdata, &fdata, GIFLZWCOMP );   // or GIFNOCOMP 
      }
   freeimage(&desimg);

   return (rcode);
}
This example creates an animated GIF that displays the image growing on a white background.





savegiftobufferex




savejpg

typedef struct { char *qualstr; int qval; } QUALVAL;

int save_jpeg(HWND hWnd, char *fname, imgdes *image, char
*qstring)
{
   int j, rcode, quality;
   static QUALVAL quallist[] = {
   {"best", 100}, {"excellent", 75}, {"good", 50},
   {"fair", 35}, {"poor", 10}};
   char szBuff[80];

   quality = 75;
   for(j=0; j<5; j++) {
      if(lstrcmpi(quallist[j].qualstr, qstring) == 0) 
         quality = quallist[j].qval;
      }

   rcode = savejpg(fname, image, quality);
   if(rcode != NO_ERROR) {
      wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   return(rcode);
}

This example saves an image as a compressed JPEG file, where the image quality factor is determined by a string argument.





savejpgex

int saveProgressiveJpeg(HWND hWnd, char *fname, imgdes *image)
{
   int j, rcode, quality = 75;
   int savemode = JPGPROG;
   char szBuff[80];

   rcode = savejpgex(fname, image, quality, savemode);
   if(rcode != NO_ERROR) {
      wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   return(rcode);
}

This example saves an image as a progressive JPEG file.


// Save an image buffer as a JPG file.
int jpegWithThumb(const char *filnam, imgdes *image, int ftype)
{
   int quality = (ftype == JPGTYP) ? 75 : 50;
   int saveMode = JPGSEQOPTTN;  // JPGSEQTN, JPGPROGTN;
   int longEdge = 100; // Maximum width or length 100 pixels

   jpegsetthumbnailsize(longEdge); 
   return(savejpgex(filnam, image, quality, saveMode));
}

This examples saves an image with a thumbnail.




savejpgtobuffer

   int saveAndLoadJpgFromBuffer(HWND hWnd, char *fname, 
   imgdes *image)
   {
      TiffData tdat;   
      JpegData jdat;      // Reserve space for struct
      imgdes timage;
      UCHAR huge *buffaddr;
      char szBuff[80];
      int rcode, qual = 75;

   // Load a TIFF file into temp image
   if((rcode = tiffinfo(fname, &tdat)) == NO_ERROR &&
      (rcode = allocimage(&timage, tdat.width, tdat.length,
    tdat.vbitcount)) == NO_ERROR &&
      (rcode = loadtif(fname, &timage)) == NO_ERROR) {

         // Save temp image as compressed JPEG data in buffer
         rcode = savejpgtobuffer(&buffaddr, &timage, qual);
         if(rcode == NO_ERROR) {
            // Done with temp image, release it
            freeimage(&timage);

            // Load the JPEG image from the buffer   
            // Get the JPEG image dimensions
            rcode = jpeginfofrombuffer(buffaddr, &jdat);
            if(rcode == NO_ERROR) {
               // Allocate a new image buffer
               rcode = allocimage(image, jdat.width, 
      jdat.length, jdat.vbitcount);
               if(rcode == NO_ERROR) {
                  // Load the compressed JPEG image
                  rcode = loadjpgfrombuffer(buffaddr, image);
                  GlobalFreePtr(buffaddr); // Done with JPEG data 
                  if(rcode == NO_ERROR) {
                     // Display pic
                     ShowWindow(hWnd, SW_SHOWNORMAL);
                     UpdateWindow(hWnd);
                     wsprintf((LPSTR)szBuff, (LPSTR)
         "File %s loaded",(LPSTR)fname);
                     MessageBox(hWnd, szBuff, 
       "Load JPEG from Buffer", MB_OK);
                     }
                  }   
               }
            }
         }
      return(rcode);
   }

The example loads a TIFF file, stores the image as compressed JPEG data in memory, and expands the JPEG data into an image buffer.




savejpgtobufferex




savepcx

int save_pcx(HWND hWnd, char *fname, imgdes *image)
{
   int rcode;
   char szBuff[80];

   rcode = savepcx(fname, image);
   if(rcode == BAD_DSK)   
      wsprintf(szBuff, "Could not save %s, disk full",
         (LPSTR)fname);
   else if(rcode == BAD_CRT)
      wsprintf(szBuff, "Could not create %s", (LPSTR)fname);
   else if(rcode == NO_ERROR)
      wsprintf(szBuff, "%s saved as %d x %d PCX file",
         (LPSTR)fname, (int)image->bmh->biWidth, 
         (int)image->bmh->biHeight);
   MessageBox(hWnd, szBuff, 0, MB_OK);
   return(rcode);
}

This example saves an image area as a PCX file.




savepng

int saveAPng(HWND hWnd, char *fname, imgdes *image)
{
   int rcode;
   int comp = PNGALLFILTERS | PNGINTERLACE;
   char szBuff[80];

   histoequalize(image, image);
   rcode = savepng(fname, image, comp);
   if(rcode != NO_ERROR) {
      wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   return(rcode);
}

This example brightens an image and saves it with maximum compression as an interlaced PNG file.





savepngtobuffer




savetga

int save_tga(HWND hWnd, char *fname, imgdes *image)
{
   int rcode;
   char szBuff[80];
   rcode = sharpen(image, image);
   if(rcode != NO_ERROR) 
      wsprintf(szBuff, "Error in sharpening image");
   else {
      rcode = savetga(fname, image, 0);
      if(rcode != NO_ERROR) 
         wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
      }
   if(rcode != NO_ERROR)
      MessageBox(hWnd, szBuff, 0, MB_OK);
   return(rcode);
}

This example sharpens an image and saves it as an uncompressed TGA file.




savetif

int save_tif(HWND hWnd, char *fname, imgdes *image)
{
#define NONE 0
#define LZW  1
#define PB   2
#define G3   3
#define G4   4
   int rcode, comp;
   char szBuff[80];

   // Use PackBits comp for 1- or 8-bit image
   comp = (image->bmh->biBitCount <= 8) ? PB : NONE;

   rcode = savetif(fname, image, comp);
   if(rcode != NO_ERROR) 
      wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
   return(rcode);
}

This example saves a 1- or 8-bit image as a compressed TIFF file and a 24-bit image as an uncompressed TIFF file.




savetifpage

void replacePageInMultiTIF(LPSTR fname, 
   imgdes far *rimage, // Image to substitute
   int newPage) // Page to replace
{
// Assume TIF file contains PAGE_MAX or less pages
#define PAGE_MAX 25

  int pageArray[PAGE_MAX];
  int j, k, min, tmp, rcode, totalPages, curPage;
  char *fname = "multiTIF.tif";
  char *tempName = "TempFile.TMP";
  TiffData tinfo;
  imgdes timage, far *simage;
  int cmprsn = 0; // Save as uncompressed TIF

  // Call tiffgetpageinfo to fill totalPages and pageArray
  rcode = tiffgetpageinfo(fname, (int far *)&totalPages,       
     (int far *)pageArray, sizeof(pageArray));
  if(rcode == NO_ERROR) {
     // Write the new file
     for(j=0; j<totalPages; j++) {
     curPage = pageArray[j];
     if(curPage == newPage) // Write current page
        simage = rimage;
     else { // Don't write current page
        // Make sure page exists and get its dimensions
        rcode = tiffinfopage(fname, &tinfo, curPage);
        // Allocate space for the page
        rcode = allocimage(&timage, tinfo.width,tinfo.length,
           tinfo.vbitcount);
        // Load the page
        rcode = loadtifpage(fname, &timage, curPage);
        simage = &timage;
        }
     // Write the page to a new file
     rcode = savetifpage(tempName, simage, cmprsn, curPage);
     if(curPage != newPage)
        freeimage(&timage); // Release page memory
     }
  // Replace fname with tempName and delete tempName
  if(rcode == NO_ERROR) {
     CopyFile(tempName, fname, FALSE); // 32-bit API function
     remove(tempName);
     }
  }
  return(rcode);
}

This example replaces page number newPage with a new image.




savetiftobuffer




setgifcomment

int save_gifcom(HWND hWnd, char *fname, imgdes *image)
{
   int rcode, gifvers = 89; // Create a GIF89a file
   char szBuff[80], *gifcomment = "File created on 4-9-94";

   // Set GIF version and add a comment to the GIF file
   //  (cannot add a comment to an GIF87a file)
   setgifcomment(gifvers, gifcomment);
   rcode = savegif(fname, image);
   if(rcode != NO_ERROR) {
      wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
   return(rcode);
}

This example saves an image as a GIF89a file and includes a comment string indicating when the image was created.




setimagearea

void ResetArea(HWND hWnd, imgdes *image)
{
   // Reset image area to the entire image
   setimagearea(image, 0, 0, (int)image->bmh->biWidth - 1,
      (int)image->bmh->biHeight - 1);
}

This example resets the image area to the entire image.




setpixelcolor

void set_icolumn(HWND hWnd, imgdes *image, int xx, int yy, 
   int pels2write, unsigned char *lnbuff) // Source of pixels 
{
   unsigned long color;
   int j, rcode=NO_ERROR;
   unsigned char red, grn, blu, mask=0x80;

   for(j=0; j<pels2write && rcode==NO_ERROR; j++) {
      if(image->bmh->biBitCount == 1) { // 1-bit image
         color = *lnbuff & mask;
         mask >>= 1;
         if(mask == 0) {
            mask = 0x80;
            lnbuff++;
            }
         }
      else if(image->bmh->biBitCount == 8) // 8-bit image
         color = *lnbuff++;
      else {   // 24-bit image
         blu = *lnbuff++;
         grn = *lnbuff++;
         red = *lnbuff++;
         color = RGB(red, grn, blu);  // Windows macro
         }
      rcode = setpixelcolor(image, xx, yy++, color);
      }
   if(rcode != NO_ERROR)
      MessageBox(hWnd, "Failure in setting pixel color", 0,
      MB_OK);
}

This example copies a row of pixels in a line buffer to a column.




setupimgdes

int GetAClipping(HWND hwnd, char *fname)
{
   unsigned char huge *dib;
   int rcode=NO_ERROR, oclip;
   HGLOBAL hMem;
   imgdes image;

   if((oclip = OpenClipboard(hwnd)) != 0) {
      // Get DIB from clipboard
      if((hMem = GetClipboardData(CF_DIB)) != 0) {
         // Get address of DIB
         dib = (unsigned char huge *)GlobalLock(hMem);

         // Describe the DIB with an image descriptor
         rcode = setupimgdes(dib, &image);
         if(rcode == NO_ERROR) 
            rcode = savebmp(fname, &image, 0);
         }
      else 
         rcode = NO_CLIPBRD_DIB;   // No DIB on clipboard
      }
   else
      rcode = NO_CLIPBRD;   // Could not open clipboard

   if(hMem)  // Unlock memory before closing the clipboard
      GlobalUnlock(hMem);
   if(oclip) 
      CloseClipboard();      // Close the clipboard
   return(rcode);
}

This example saves a DIB from the clipboard as a BMP file.




sharpen

int save_sharp(HWND hWnd, char *fname, imgdes *image)
{
   int rcode;
   char szBuff[80];

   rcode = sharpen(image, image);
   if(rcode != NO_ERROR) 
      wsprintf(szBuff, "Error in sharpening image");
   else {
      rcode = savebmp(fname, image, 0);
      if(rcode != NO_ERROR) 
         wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
      }
   if(rcode != NO_ERROR)
      MessageBox(hWnd, szBuff, 0, MB_OK);
   return(rcode);
}

This example sharpens an image and saves it as a BMP file.




sharpengentle

int save_gentle(HWND hWnd, char *fname, imgdes *image)
{
   int rcode;
   char szBuff[80];

   rcode = sharpengentle(image, image);
   if(rcode != NO_ERROR) 
      wsprintf(szBuff, "Error in sharpening image");
   else {
      rcode = savetif(fname, image, 0);
      if(rcode != NO_ERROR) 
         wsprintf(szBuff, "Could not save %s", (LPSTR)fname);
      }
   if(rcode != NO_ERROR)
      MessageBox(hWnd, szBuff, 0, MB_OK);
   return(rcode);
}

This example gently sharpens an image and saves it as a TIFF file.




standardpalette




subimage

int sub2(HWND hWnd, imgdes *image1, imgdes *image2, 
   imgdes *image3)
{
   int rcode;

   if((rcode=blur(image1, image2)) == NO_ERROR) {
      if((rcode=subimage(image1, image2, image3)) != NO_ERROR)
         MessageBox(hWnd, "Error in subtracting images", 0,
         MB_OK);
      }
   else
      MessageBox(hWnd, "Error in blurring images", 0, MB_OK);
   return(rcode);
}

This example smooths image1, subtracts the smoothed image from the original, and places the difference in image3.

tgainfo




threshold

int thresh15(HWND hWnd, imgdes *image)
{
   int rcode, max_black=15;
   
   setimagearea(image, 0, 0, (unsigned)image->bmp->biWidth-1,
      (unsigned)image->bmh->biHeight-1);
   rcode = threshold(max_black, image, image);
   if(rcode != NO_ERROR)
      MessageBox(hWnd, "Error at threshold", 0, MB_OK);
   return(rcode);
}

This example resets the image area to the entire image, and sets all brightness levels less than or equal to 15 to black.




tiffgeterror

int loadATiffFile(HWND hWnd, char *fname, imgdes *image)
{
   TiffData tdat;
   int rcode;

   // Get info on the file we're to load
   rcode = tiffinfo(fname, &tdat);
   if(rcode == NO_ERROR) { // Fill structure
      // Allocate space for an image
      rcode = allocimage(image, (int)tdat.width, (int)tdat.length, tdat.vbitcount);
      if(rcode == NO_ERROR) {
         // Load image
         rcode = loadtif(fname, image);
         if(rcode == BAD_TIFF) {
            char szBuff[128];
            // Get extended error info
            int extRcode = tiffgeterror();
            wsprintf(szBuff, "Error in loading %s: extended error code %d", (LPSTR)fname, extRcode);
            MessageBox(hWnd, szBuff, 0, MB_OK);
            }
         freeimage(image); // Free image on error
         }
      }
   return(rcode);
}

This function reports extended error information when a TIFF file cannot be loaded.




tiffgetpageinfo




tiffgetxyresolution




tiffgetxyresolutionpagebyindex




tiffinfo

void tiffidentity(HWND hWnd, char *fname)
{
   TiffData tdat;       // Reserve space for structure 
   int rcode;
   char szBuff[80];

   if((rcode=tiffinfo(fname, &tdat)) == BAD_OPN)
      wsprintf(szBuff, "Could not find %s", (LPSTR)fname);
   else if(rcode == BAD_TIFF)
      wsprintf(szBuff, "%s is not a TIFF file", (LPSTR)fname);
   else { // Is it an RGB TIFF? 
      if(tdat.SamplesPPixel == 3 && tdat.PhotoInt == 2 && 
         tdat.BitsPSample == 8) 
         wsprintf(szBuff, "%s is a RGB TIFF file", (LPSTR)fname);
      // Is it a palette color TIFF? 
      else if(tdat.SamplesPPixel == 1 && tdat.PhotoInt == 3)
         wsprintf(szBuff, "%s is a palette color TIFF file",
            (LPSTR)fname);
      // Is it a grayscale TIFF? 
      else if(tdat.SamplesPPixel == 1 && tdat.PhotoInt <= 1)
         wsprintf(szBuff, "%s is a grayscale TIFF file", 
            (LPSTR)fname);
      // Is it a bilevel TIFF? 
      else if(tdat.SamplesPPixel == 1 && tdat.BitsPSample == 1
         && tdat.PhotoInt <= 1)  
         wsprintf(szBuff, "%s is a bilevel TIFF file",
            (LPSTR)fname);
      else wsprintf(szBuff, "%s is a TIFF file of unknown type",
         (LPSTR)fname);
      }
   MessageBox(hWnd, szBuff, 0, MB_OK);
} 

This example identifies a file as a grayscale, bilevel, palette color, or RGB TIFF file.




tiffinfofrombuffer




tiffinfopagebyindex




tiffinfopagebyindexex




tiffinfopagebyindexfrombuffer




tiffinfopagebyindexfrombufferex




tiffinfopage




tiffsetxyresolution




TWclose




TWdetecttwain

void EnableTwainScanMenuItems(HWND hWnd, HMENU hMenu) 
{
   static BOOL scanDriverReady = FALSE;
   int mstate;

   // Enable/disable scan menu items
   if(scanDriverReady == FALSE) {
      // Enable/disable scan menu items
      mstate = MF_GRAYED;
   // If Twain source manager (TWAIN.DLL or TWAIN_32.DLL) 
      // is present, enable the scan menu items
      if(TWdetecttwain(hWnd) == NO_ERROR) {
         scanDriverReady = TRUE;
         mstate = MF_ENABLED;
         }
      EnableMenuItem(hMenu, IDM_F_SELECTSOURCE, mstate);
      EnableMenuItem(hMenu, IDM_F_ACQUIRE, mstate);
      }
}

This example enables or disables the TWAIN scan menu items.




TWgetcontrast




TWgetmeasureunit




TWgetphysicalsize



TWsetduplx




TWsetpagesize

int AcquireAnImageDup(HWND hWnd, imgdes far *desimg)
{
   int rcode;
   int width, height;
   BOOL enableduplex = TRUE;
   unsigned pagesize = 0; // TWSS_NONE, for largest page size

   TWgetphysicalsize(hWnd, &width, &height);
  
   // Enable (or disable) duplex operation
   TWsetduplex(hWnd, enableduplex);  

   // Set maximum page size
   TWsetpagesize(hWnd, pagesize);   
   // Acquire image from selected/default source
   rcode = TWscanimage(hWnd, desimg);
   if(rcode != NO_ERROR){ // Handle any errors
      char szBuff[80];
      wsprintf(szBuff, "Error in acquiring image: %d, %d",
         rcode, TWgeterror());
      MessageBox(hWnd, szBuff, "TWAIN Error", MB_OK);
      }
   return(rcode);
}

This example gets the physical scan limits, enables duplex operation, sets the maximum page size, and acquires an image.




TWgetsourcenames

TWselectsourcebyname

TWsetproductname

int SelectDataSourceByName(HWND hWnd)
   int j, rcode;
   char far *targetDS="DeskScan II"; // HP ScanJet data source
   TW_STR32 far *nameList; // List of Twain data sources
   int nameCount; // Number of sources in nameList
    
   // Store App name to display in Source dialog box
   TWsetproductname("My App");

   nameList = NULL;
   // Get number of data sources available
   rcode = TWgetsourcenames(hWnd, nameList, &nameCount);

   // Allocate space for names of data sources
   nameList = (TW_STR32 far *)calloc(nameCount, sizeof(TW_STR32));

   // Get data source names
   rcode = TWgetsourcenames(hWnd, nameList, &nameCount);
   if(rcode == NO_ERROR) {
      // Compare data source names found to our target
      for(j=0; j<nameCount; j++) {
         if(lstrcmpi(targetDS, (char far *)&nameList[j]) == 0)
            break; // Found a match
         }
      if(j == nameCount)
         rcode = TWAIN_NODS;  // Target data source not found
      else // Select the data source for image acquisition
         rcode = TWselectsourcebyname(hWnd, (char far *)&nameList[j]);
      }
   if(nameList)
      free(nameList);
   return(rcode);
}

This example retrieves a list of TWAIN data sources and then selects the data source for the HP ScanJet scanner.




TWgetxresolution




TWgetyresolution




TWopen

int AcquireAnImage2(HWND hWnd, imgdes far *desimg)
{
   int rcode;  // Set App name to display in source dialog
   TWsetproductname("OurApp");
   rcode = TWopen(hWnd); // Open Data Source and source mgr
   if(rcode == NO_ERROR) 
      // Acquire image from selected/default source
      rcode = TWscanimage(hWnd, desimg);
   return(rcode);
}
This example acquires an image from a TWAIN source using the TWopen function.


TWgetfeeder

TWsetfeeder

TWscancountimages

int _export WINAPI saveImage(imgdes far *simage)
{
   static int imgCtr = 0;     // Count scanned images
   int rcode;
   TCHAR filnam[256];

   // Create a filename to save the scanned image
   wsprintf(filnam, (LPSTR)_T"test%d.tif", imgCtr);

   // Expand image contrast
   expandcontrast(20, 240, simage, simage);

   // Save the image
   rcode = savetif(filnam, simage, 0);

   if(rcode == NO_ERROR)
      imgCtr++;                  // Update image counter
   else
      rcode = TWAIN_STOP_SCAN;   // Quit if error

   // Free image buffer after it's saved
   freeimage(simage);
   return(rcode);
}

// Acquire command selected
int AcquireCountImages(HWND hWnd)
{
   int rcode;
   imgdes simage;
   int maxPages = 20;          // Acquire up to 20 images
   BOOL showUI = FALSE;        // Hide user interface
   BOOL feederEnabled;         // If TRUE, ADF enabled
   BOOL feederLoaded;          // If TRUE, ADF has paper
   TWAIN_CAP_DATA newXRes;     // For setting scan resolution
   TWAIN_CAP_DATA newPixType;  // For setting scan bits per pixel

   // Specify scan area in mils
   static RECT scanRc = { 0, 0, 8500, 11000 }; // lf,tp,rt,bt

   TWsetfeeder(hWnd, TRUE);                 // Enable ADF
   TWgetfeeder(hWnd, &feederEnabled, &feederLoaded); 

   // Set scanning mode (this is optional)
   newPixType.conType = TWON_ONEVALUE;      // Container type
   // TWPT_BW=0, TWPT_GRAY, TWPT_RGB, TWPT_PALETTE,
   newPixType.oneValue.val = TWPT_GRAY;     // Acquire grayscale image
   rcode = TWsetpixeltype(hWnd, &newPixType);

   // Set scanning resolution (this is optional)
   newXRes.conType = TWON_ONEVALUE;         // Container type
   newXRes.oneValue.val = 200;              // resolution = 200 dpi
   rcode = TWsetxresolution(hWnd, &newXRes);
   rcode = TWsetyresolution(hWnd, &newXRes);

   // Acquire maxPages images, save to disk via saveImage()
   rcode = TWscancountimages(hWnd, &simage, NULL, showUI,
      maxPages, saveImage);

   if(rcode != NO_ERROR){ // Handle any errors
      TCHAR szBuff[80];
      wsprintf(szBuff, _T("Error in acquiring image: %d, %d"),
         rcode, TWgeterror());
      MessageBox(hWnd, szBuff, _T("TWAIN Error"), MB_OK);
      }
   return(rcode);
}

This example acquires up to 20 images from a TWAIN source and stores them as individual TIFF files.




TWgeterror

TWscanimage

int AcquireAnImage(HWND hWnd, imgdes far *desimg)
{
   int rcode;
   
   // Store App name to display in Source dialog box. 
   // String may contain up to 32 chars.
   TWsetproductname("OurApp");

   // Acquire image from selected/default source
   rcode = TWscanimage(hWnd, desimg);
   if(rcode != NO_ERROR){ // Handle any errors
      char szBuff[80];
      wsprintf(szBuff, "Error in acquiring image: %d, %d",
         rcode, TWgeterror());
      MessageBox(hWnd, szBuff, "TWAIN Error", MB_OK);
      }
   return(rcode);
}

This example acquires an image from a TWAIN source and stores it in an image buffer.




TWscanimageex

int AcquireSmallImage(HWND hWnd, imgdes *desimg)
{
   int rcode;
   // Area to scan: 1.25 inches from left, 0.0 inches from
   // top, end at 3.0 inches from left and 3.5 inches from top
   static RECT scanRc = { 1250, 0, 3000, 3500 }; // lf,tp,rt,bt
   BOOL showUI = FALSE; // Don't display acquire dialog
   TWAIN_CAP_DATA newXRes;
   TWAIN_CAP_DATA newBrt;
   TWAIN_CAP_DATA newPixType;

   // Store App name to display in Source dialog box. 
   // String may contain up to 32 chars.
   TWsetproductname("OurApp");

   newPixType.conType = TWON_ONEVALUE; // Container type
   // TWPT_BW=0, TWPT_GRAY, TWPT_RGB, TWPT_PALETTE,
   // Acquire RGB image 
   newPixType.oneValue.val = TWPT_RGB; 
   rcode = TWsetpixeltype(hWnd, &newPixType);

   newBrt.conType = TWON_ONEVALUE; // Container type
   newBrt.oneValue.val = 200;
   rcode = TWsetbrightness(hWnd, &newBrt);

   newXRes.conType = TWON_ONEVALUE; // Container type
   newXRes.oneValue.val = 150; // 150 dpi
   rcode = TWsetxresolution(hWnd, &newXRes);
  
   // Acquire image from selected/default source
   // without acquire dialog 
   rcode = TWscanimageex(hWnd, desimg, &scanRc, showUI);
   if(rcode != NO_ERROR){ // Handle any errors
      char szBuff[80];
      wsprintf(szBuff, "Error in acquiring image: %d, %d",
         rcode, TWgeterror());
      MessageBox(hWnd, szBuff, "TWAIN Error", MB_OK);
      }
   return(rcode);
}

This example sets the pixel type, brightness, and horizontal resolution, and acquires an image from a TWAIN source without displaying the acquire dialog box.




TWscanmultipleimages

static int imgCtr = 0; // Counts scanned images
int _export WINAPI saveScannedImage(imgdes far *simage)
{
   int rcode;
   char filnam[64];

   // Create a filename to save the scanned image
   wsprintf((LPSTR)filnam, (LPSTR)"test%d.tif", imgCtr);
   // Save the image
   rcode = savetif(filnam, simage, 0);
   if(++imgCtr >= 10) 
      rcode = TWAIN_STOP_SCAN;   // Quit after 10 images
   // Free image buffer after it's saved
   freeimage(simage);
   return(rcode);
}

// Acquire command selected
int AcquireMultipleImages(HWND hWnd)
{
   int rcode;
   imgdes simage;
   
   imgCtr = 0;  // Initialize image counter

   // Store App name to display in Source dialog box.
   // String may contain up to 32 chars.
   TWsetproductname("MyApp");

   // Acquire images and save to disk via saveScannedImage()
   rcode = TWscanmultipleimages(hWnd, &simage, saveScannedImage);

   if(rcode != NO_ERROR){ // Handle any errors
      char szBuff[80];
      wsprintf(szBuff, "Error in acquiring image: %d, %d",
         rcode, TWgeterror());
      MessageBox(hWnd, szBuff, "TWAIN Error", MB_OK);
      }
   return(rcode);
}

This example acquires up to 10 images from a TWAIN source and stores them as TIFF files.




TWscanmultipleimagesex




TWselectsource

int SelectDefaultSource(HWND hWnd)
{
   // Call the TWAIN source manager to select a data source 
   // for image acquisition
   return(TWselectsource(hWnd));
}

The example allows the user to select a new TWAIN data source.




TWselectsourcebyname

int SelectSourceByName(HWND hWnd)
{
   LPCSTR dsname = "Logitech ScanMan";

   // Select the ScanMan data source for image acquisition
   return(TWselectsourcebyname(hWnd, dsname));
}

The example selects a TWAIN data source for use with the Logitech ScanMan scanner.




TWgetbrightness

TWsetbrightness

int setTWbright(HWND hWnd, int newbright) // newbright is 0 - 255
{
   int slope, rcode;
   TWAIN_CAP_DATA curBrt, newBrt;

   rcode = TWgetbrightness(hWnd, &curBrt);
   // If brightness is returned in a range container
   if(curBrt.conType == TWON_RANGE) {
      slope = (curBrt.range.max - curBrt.range.min) / 255;  
      newBrt.oneValue.val = slope * newbright + curBrt.range.min;
      newBrt.conType = TWON_ONEVALUE; // Container type
      rcode = TWsetbrightness(hWnd, &newBrt);
      }
   return(rcode);
}

This example sets the brightness of a TWAIN device given a brightness value between 0 and 255.




TWsetcontrast




TWsetmeasureunit




TWsetpagesize




TWgetpixeltype

TWsetpixeltype

int setTWpixeltype(HWND hWnd)
{
   int rcode, j, k;
   TWAIN_CAP_DATA curPT, newPT;
   // Pixel types, listed in preferred order
   int preferred_types[3] = {TWPT_RGB, TWPT_GRAY, TWPT_BW};

   rcode = TWgetpixeltype(hWnd, &curPT);
   // If pixel type is returned in a range container
   if(curPT.conType == TWON_ENUMERATION) {
      newBrt.oneValue.val = curPT.enumType.array[0];  
      for(k = 0; k < 3; k++) {
         for(j = 0; j < curPT.enumType.nelems; j++) {
            if(preferred_types[k] == curPT.enumType.array[j]) {
               newPT.oneValue.val = preferred_types[k];  
               goto setPT;
               }
            }
         }
setPT:
      newPT.conType = TWON_ONEVALUE; // Container type
      rcode = TWsetpixeltype(hWnd, &newPT);
      }
   return(rcode);
}

The example sets the pixel type of a TWAIN device to one of the preferred types given.




TWsetxresolution




TWsetyresolution




TWStaticLibStart

int InitInstance(LPCSTR lpCmdLine, int nCmdShow)
{
   HWND hWndMain = CreateWindow("AppName",
      "AppName", WS_CAPTION | WS_SYSMENU, 
      0, 0, 640, 480, 0, 0, hInstance, 0); 

   if(hWndMain) {
      // Initialize static Victor Library
      VicLibStart();

      // Initialize static Victor Library TWAIN Support Module
      TWStaticLibStart(hInstance);

      . . . 
      // Init application
      if(InitLoadNSho(hWndMain) != NO_ERROR)
         PostMessage(hWndMain, WM_DESTROY, 0, 0);
      ShowWindow(hWndMain, nCmdShow); // Display main window
      UpdateWindow(hWndMain);
      return(TRUE);
      }
   return(FALSE);
}

This example function includes code that initializes the static linkable Victor Library.




TWStaticLibTerm

void DoDestroy(HWND hWnd)
{
   TWclose(); // If opened close TWAIN data source and data source manager
   TWStaticLibTerm(); // Termination routine for static Vic Twain module
   VicLibTerm();
   . . .
   PostQuitMessage(0);  // Quit the application
}

The example function includes code that terminates the Victor Twain support module.




TWvicversion

void showVicTWVersion(HWND hWnd, char *fname, imgdes *image)
{
   WORD version;
   char szBuff[80];

   version = TWvicversion();
   wsprintf(szBuff, "Victor Library TWAIN Support Module\n"
      "Version %d.%02d", HIBYTE(version), LOBYTE(version));
   MessageBox(hWnd, szBuff, 0, MB_OK);
}

This example displays the Victor Library TWAIN support module version number in a message box.




unlockLZW

#define LZWKEY 1234      // Not a valid key - example only
. . .
unlockLZW(LZWKEY);       // Enable LZW functionality
. . .

This code fragment enables loading and saving GIF and TIFF-LZW files.




updatebitmapcolortable

int updateTifBitmap(HWND hWnd, char *fname, imgdes *image)
{
   char szBuff[80];
   TiffData tdat;
   int rcode;

      // Get info on the file we're to load
      rcode = tiffinfo(fname, &tdat); // Fill structure
      if(rcode == NO_ERROR) {
         // Allocate space for an image in global memory
         rcode = allocimage(image, tdat.width, tdat.length, tdat.vbitcount);
         if(rcode == NO_ERROR) {
            rcode = loadtif(fname, image);
            if(rcode == NO_ERROR)
               // Update color table associated with image->hBitmap
               updatebitmapcolortable(image);
            }
         }
      // If there is an error, free image and display message
      if(rcode != NO_ERROR) {
         freeimage(image);
         wsprintf(szBuff, "Could not load %s", fname);
         MessageBox(hWnd, szBuff, 0, MB_OK);
         }
      return(rcode);
}



usetable

#include <math.h>

void gogamma(HWND hWnd, imgdes *image, double gamma) 
{
   double newvalue;
   int j;-
   unsigned char newtab[256];
   char szBuff[80];

   // Gamma correction: newvalue = (value/255) ** gamma * 255 
   for(j=0; j<256; j++) {    // Create a lookup table 
      // newvalue = 0 to 1
      newvalue = pow((double)j / 255.0, gamma);
      newtab[j] = (unsigned char)(newvalue * 255.0);
      }

   if(usetable(newtab, newtab, newtab, image, image) !=
      NO_ERROR) {
      wsprintf(szBuff,"Error at usetable(), gamma: %f", gamma);
      MessageBox(hWnd, szBuff, 0, MB_OK);
      }
}



VicLibStart

int InitInstance(LPCSTR lpCmdLine, int nCmdShow)
{
   HWND hWndMain = CreateWindow("AppName",
      "AppName", WS_CAPTION | WS_SYSMENU, 
      0, 0, 640, 480, 0, 0, hInstance, 0); 

   if(hWndMain) {
      // Initialize static Victor Library
      VicLibStart();
      . . . 
      // Init application
      if(InitLoadNSho(hWndMain) != NO_ERROR)
         PostMessage(hWndMain, WM_DESTROY, 0, 0);
      ShowWindow(hWndMain, nCmdShow); // Display main window
      UpdateWindow(hWndMain);
      return(TRUE);
      }
   return(FALSE);
}

This example function includes code that initializes the static linkable Victor Library.




VicLibTerm

void DoDestroy(HWND hWnd)
{
   . . .
   VicLibTerm(); // Termination routine for static Victor Library
   PostQuitMessage(0);  // Quit the application
}

The example function includes code that terminates the static Victor Library.




Victorversion

void showVicVersion(HWND hWnd, char *fname, imgdes *image)
{
   WORD version;
   char szBuff[80];

   version = Victorversion();
   wsprintf(szBuff, "Victor Library version %d.%02d",
      HIBYTE(version), LOBYTE(version));
   MessageBox(hWnd, szBuff, 0, MB_OK);
}

This example displays the Victor Library version number in a message box.




Victorversiondate

// Processes messages for "About" dialog box 
int _export WINAPI About(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
   TCHAR buff[128];
   WORD version;

   (void)lParam;
   switch(msg) {
      case WM_INITDIALOG:
         {
         VIC_VERSION_INFO vicVSInfo;
         TCHAR versionDate[64];

         CenterDlgBox(hDlg);   // Center the dialog box
         // Display VicDemo version
         version = appVersion();
         wsprintf(buff, (LPTSTR)_T("Victor Demo Program version %d.%02d"),
            HIBYTE(version), LOBYTE(version));
         SetDlgItemText(hDlg, IDC_VAL1, buff);

         // Display Victor Library version
         Victorversionex(&vicVSInfo);
         wsprintf(buff, (LPTSTR)_T("Victor Library version %d.%02d,%02d"),
            HIBYTE(vicVSInfo.version), LOBYTE(vicVSInfo.version),
            vicVSInfo.flags);
         SetDlgItemText(hDlg, IDC_VAL2, buff);

         // Display Victor Library creation date
         Victorversiondate(versionDate, sizeof(versionDate)/sizeof(TCHAR));
         wsprintf(buff, (LPTSTR)_T("Lib created: %s"), versionDate);
         SetDlgItemText(hDlg, IDC_VAL3, buff);
         return(TRUE);
         }

      case WM_COMMAND:
         if(LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
            EndDialog(hDlg, TRUE);
            return(TRUE);
            }
         break;
      }
   return(FALSE);

}




Victorversionex

void showVicVersionex(HWND hWnd, char *fname, imgdes *image)
{
   char szBuff[80];
   VIC_VERSION_INFO verinfo;

   Victorversionex(&verinfo);
   wsprintf(szBuff, "Victor Library version %d.%02d,%02d",
      HIBYTE(verfino.version), LOBYTE(verinfo.version),
         verinfo.flags); 
   MessageBox(hWnd, szBuff, 0, MB_OK);
}

This example displays the Victor Library version information in a message box.




victowinpal

HPALETTE HPalette;

void setpalette(HWND hWnd, imgdes *image)
{
   HDC hdc;
   int DisplayBits;

   hdc = GetDC(hWnd);
   DisplayBits = GetDeviceCaps(hdc, BITSPIXEL);
   if(DisplayBits <= 8) {
      // Delete palette object previously created by victowinpal()
      if(HPalette)
         DeleteObject(HPalette);

      // Create and realize a logical palette
      victowinpal(image, &HPalette);
      HPalette = SelectPalette(hdc, HPalette, 0);
      RealizePalette(hdc);
      // Remove logical palette before releasing DC
      HPalette = SelectPalette(hdc, HPalette, 0);
      }
   ReleaseDC(hWnd, hdc);
}

This example creates, selects, and realizes a logical palette for image display.




viewimage

// Function UpdateScrollRange is defined in viewimageex() example
imgdes Image;
HPALETTE hPalette;
HDC hdc;
PAINTSTRUCT ps;
HCURSOR hSaveCursor;
int xpos, ypos;
   .
   .
   .
   case WM_SIZE:         // Size of window has changed!
      UpdateScrollRanges(hWnd, &Image);
      break;

   case WM_PAINT:         // Repaint a portion of the window!
      hdc = BeginPaint(hWnd, &ps);
      // Display hourglass cursor  
      hSaveCursor = SetCursor(LoadCursor(0, IDC_WAIT));      
      // Delete palette allocated by previous viewimage()
      if(hPalette)
         DeleteObject(hPalette);
      xpos = GetScrollPos(hWnd, SB_HORZ);
      ypos = GetScrollPos(hWnd, SB_VERT);
      rcode = viewimage(hWnd, hdc, &hPalette, xpos, ypos, &Image);
      SetCursor(hSaveCursor); // Restore cursor 
      EndPaint(hWnd, &ps);
      break;
   .
   .
   .

This code displays an image in a window upon receiving a WM_PAINT message.




viewimageex

imgdes Image;
HPALETTE hPalette;
POINT ptScrn={10, 10}; // Display image at window offset (10,10)
       
// Repaint a portion or all of the window
void DoPaint(HWND hWnd)
{
   PAINTSTRUCT ps;   // Holds PAINT info
   HDC hdc;
   int rcode, xpos, ypos;

   hdc = BeginPaint(hWnd, &ps);
   // Get the position of the upper left corner in the image
   xpos = GetScrollPos(hWnd, SB_HORZ);
   ypos = GetScrollPos(hWnd, SB_VERT);
   if(hPalette) // Delete palette object allocated by viewimageex()
   DeletePalette(hPalette);
   rcode = viewimageex(hWnd, hdc, &hPalette, xpos, ypos, &Image,
     ptScrn.x, ptScrn.y, VIEWDITHER);
   EndPaint(hWnd, &ps);
   // Handle any errors here
}

// Size of window has changed!
void DoSize(HWND hWnd, UINT state, int cx, int cy)
{
   UpdateScrollRanges(hWnd, &Image);
}

// Set scroll ranges to allow using scroll box position in
// viewimageex function
void UpdateScrollRanges(HWND hwnd, imgdes *image)
{
   RECT rc;
  int vert_range, horiz_range, j, xpos, ypos;
  static int flag;

  if(flag == 0) { // Enter ftn only if we're not already here
  flag++;
  for(j=0; j<2; j++) {
  GetClientRect(hwnd, &rc);
  // Calc horizontal scroll range
  horiz_range = (unsigned)image->bmh->biWidth - 
  rc.right + ptScrn.x;
  if(horiz_range < 0)
  horiz_range = 0;
  SetScrollRange(hwnd, SB_HORZ, 0, horiz_range, TRUE);

  //  Calc vertical scroll range
  vert_range = (unsigned)image->bmh->biHeight - 
  rc.bottom + ptScrn.y;
  if(vert_range < 0)
  vert_range = 0;
  SetScrollRange(hwnd, SB_VERT, 0, vert_range, TRUE);

  // Redraw window if a scroll position is out of range
  xpos = GetScrollPos(hwnd, SB_HORZ);
  ypos = GetScrollPos(hwnd, SB_VERT);
  if(ypos > vert_range || xpos > horiz_range)
  InvalidateRect(hwnd, 0, TRUE);
  }
  flag--;
  }
}

This code displays an image in a window upon receiving a WM_PAINT message.




windowtoimage

int CaptureScreenWindow(HWND hWnd)
{
   int rcode;
   imgdes timage;
   char *fname = "window.tif";

   // Capture window as Victor image
   rcode = windowtoimage(hWnd, &timage);
   if(rcode == NO_ERROR) {
      // Save captured window
      rcode = savetif(fname, &timage, 0);
      // Release memory allocated by windowtoimage()
      freeimage(&timage);
      }
   return(rcode)
}

This example captures a window's area and saves it as a TIFF file.




wintovicpal

int pastepal(HWND hWnd, imgdes *image)
{
   int rcode;
   HPALETTE hPal;

   if(OpenClipboard(hWnd)) {
      if(hPal = GetClipboardData(CF_PALETTE)) {
         // Copy the palette data into image->palette
         rcode = wintovicpal(hPal, image);
         }
       CloseClipboard();
       }
   else
      rcode = NO_CLIPBRD;
   return(rcode);
}

This example retrieves a logical palette from the clipboard and uses it to create an image palette.




wtaverage

void brighten_shadows(HWND hWnd, imgdes *image1, imgdes *image2)
{
   int rcode, weight=50;

   // Make very dark portions of the picture visible
   rcode = expandcontrast(0, 60, image1, image2);
   if(rcode == NO_ERROR) {
      // Combine with original image to create balanced image
      rcode=wtaverage(weight, image1, image2, image2);
      if(rcode != NO_ERROR) 
         MessageBox(hWnd, "Error at wtaverage()", 0, MB_OK);
      }
   else
      MessageBox(hWnd, "Error at expandcontrast()", 0, MB_OK);
}

This example improves the visibility of the dark areas of an image without destroying the visibility of the bright regions.




xorimage

int zero_imagearea(HWND hWnd, imgdes far *image1)
{
   int rcode;

   if((rcode=xorimage(image1, image1, image1)) != NO_ERROR)
      MessageBox(hWnd, "Error in XORing images", 0, MB_OK);
   return(rcode);
}

This example zero's the image buffer by XORing each pixel with itself.




zeroimage

int clear_imagebuffer(HWND hWnd, imgdes *image)
{
   int rcode, newvalue=128; 

   setimagearea(image, 0, 0, (UINT)image->bmh->biWidth-1,
      (UINT)image->bmh->biHeight-1);
   if((rcode=zeroimage(newvalue, image)) != NO_ERROR)
      MessageBox(hWnd, "Error in clearing buffer", 0, MB_OK);
   return(rcode);
}

This example sets the image area to the size of the entire buffer, and sets all pixels to 128.




zeroimgdes

void free_image(imgdes *image)
{
   HGLOBAL hMem;

   hMem = GlobalPtrHandle(image->bmh); // Macro in WINDOWSX.H
   if(hMem) {
      GlobalUnlock(hMem);
      GlobalFree(hMem);
      zeroimgdes(image);   // Zero the image descriptor
    }
}

This example frees the memory assigned to a packed DIB and zeros the image descriptor.