Click here to Skip to main content
15,895,667 members
Articles / Desktop Programming / MFC

Extendable Webserver

Rate me:
Please Sign up or sign in to vote.
3.67/5 (8 votes)
6 Mar 2003CPOL2 min read 80.9K   1.7K   21  
An example of an extendible webserver using PJ Naughter's MFC library
// ** JPEG.CPP, the code used to wrap IJL

#include "..\stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "dibapi.h"

#include "jpegWrap.h"

//############################################################################
//##                                                                        ##
//##  JPEG.CPP                                                              ##
//##                                                                        ##
//##  Wrapper class to load a jpeg from a block of memory.                  ##
//##                                                                        ##
//##  OpenSourced 2/4/2000 by John W. Ratcliff                              ##
//##                                                                        ##
//##  No warranty expressed or implied.  Released as part of the triangle   ##
//##  throughput testbed project.                                           ##
//############################################################################
//##                                                                        ##
//##  Contact John W. Ratcliff at jratcliff@verant.com                      ##
//############################################################################
//##																	    ##
//##  Added HBitmap routine, can do a scaling and adding text at top of jpg ##
//##  edgar@cyberpoint.nl
//############################################################################
#include "ijl.h" // intel jpeg library header file.


bool Jpeg::GetBitmapBits( TCHAR* StrText,
							 HBITMAP hbm, 
							 unsigned char ** ppPicture, 
							 unsigned long * pnPictureBytes,
							 int iW,
							 int iH,
							 int iQ)
{
	bool ret = false;

	BITMAP bitmapOrg;
	HBITMAP bmpUseThisOne = hbm;

	int iOrgX = 1;
	int iOrgY = 1;

	// When we have a text, increase height of destination bmp with 16 ( must be multiple of 16 )
	int iOffsetY = ( StrText && _tcslen(StrText)) ? 16 : 0;

	if ( sizeof(BITMAP) == ::GetObject( hbm, sizeof(BITMAP), &bitmapOrg ) )
	{
		iOrgX = bitmapOrg.bmWidth;
		iOrgY = bitmapOrg.bmHeight;

		iW = abs(iW?iW:iOrgX);
		iH = abs(iH?iH:iOrgY);

		iH += iOffsetY;

		// Allways multiple of 16
		iW = (iW/16)*16;
		iH = (iH/16)*16;
		
		// Create a bitmap compatible to the screen
		HDC hdcOrg = CreateCompatibleDC( NULL );
		HDC hdcSize = CreateCompatibleDC( NULL );

		HBITMAP hbmSized = NULL;
		HBITMAP hBmpSized = NULL;

		if ( hdcSize )
		{
			HGDIOBJ pOrg = SelectObject ( hdcOrg, hbm );
			hBmpSized = ::CreateCompatibleBitmap (hdcOrg,iW,iH);

			if ( hBmpSized )
			{
				HGDIOBJ p = SelectObject ( hdcSize, hBmpSized );

				CRect DCRect(0,0,iW,iH);
				CRect DibRect(0,0,iOrgX,iOrgY);

				::SetStretchBltMode ( hdcSize,	COLORONCOLOR );
				::SetStretchBltMode ( hdcOrg,	COLORONCOLOR );

				::StretchBlt ( hdcSize, 0,iOffsetY,iW,iH-iOffsetY,hdcOrg,0,0,iOrgX,iOrgY,SRCCOPY);

				// Draw text at top of bitmap
				// Only needed when we have set an offset
				if ( iOffsetY )
				{
					::SetBkColor ( hdcSize, RGB ( 0,0,0 ) );
					::SetTextColor ( hdcSize, RGB( 255,255,255));
					::DrawText ( hdcSize, StrText,-1,&DCRect,DT_TOP|DT_EXPANDTABS );
				}

				SelectObject ( hdcSize, p );
				bmpUseThisOne = hBmpSized;
			}
			SelectObject ( hdcOrg, pOrg );
			DeleteDC ( hdcSize );
			DeleteDC ( hdcOrg );
		}


		// Changes a HBITMAP to a 24 bit DIB
		HDIB hDib = BitmapToDIB ( bmpUseThisOne, NULL );
		::DeleteObject ( hBmpSized );

		if ( hDib )
		{
		   LPSTR lpDIBHdr, lpDIBBits;  // pointer to DIB header, pointer to DIB bits
		   /* if invalid handle, return NULL */

		   /* lock memory block and get a pointer to it */
		   lpDIBHdr = (char *)GlobalLock(hDib);

		   if ( lpDIBHdr )
		   {
			   /* get a pointer to the DIB bits */
			   lpDIBBits = FindDIBBits(lpDIBHdr);
			   
			   int iLen = 0;
			   void* p = Jpeg::Compress( lpDIBBits,iW,iH,3/*24bit=3Byte*/,iLen,iQ );
			   if ( p )
			   {
				   // JetJPG as return
				   *ppPicture = (unsigned char *)p;
				   *pnPictureBytes = iLen;

					ret = true;
			   }

			   GlobalUnlock(hDib);
			}
			else
			{
				delete[] *ppPicture;
				*ppPicture = NULL;

				*pnPictureBytes = 0;
			}
		}
		DestroyDIB ( hDib );
	}

	return ret;
}

// read image into this buffer.
void * Jpeg::ReadImage(int &width,
                       int &height,
                       int &nchannels,
                       const void *buffer,
                       int sizebytes)
{
  JPEG_CORE_PROPERTIES jcprops;

  if ( ijlInit(&jcprops) != IJL_OK )
  {
    ijlFree(&jcprops);
    return 0;
  }

  jcprops.JPGBytes = (unsigned char *) buffer;
  jcprops.JPGSizeBytes = sizebytes;
  jcprops.jquality = 100;

  if ( ijlRead(&jcprops,IJL_JBUFF_READPARAMS) != IJL_OK )
  {
    ijlFree(&jcprops);
    return 0;
  }

  width  = jcprops.JPGWidth;
  height = jcprops.JPGHeight;
  IJLIOTYPE mode;

  mode = IJL_JBUFF_READWHOLEIMAGE;
  nchannels = jcprops.JPGChannels;
  unsigned char * pixbuff = new unsigned char[width*height*nchannels];
  if ( !pixbuff )
  {
    ijlFree(&jcprops);
    return 0;
  }

  jcprops.DIBWidth  = width;
  jcprops.DIBHeight = height;
  jcprops.DIBChannels = nchannels;
  jcprops.DIBPadBytes = 0;
  jcprops.DIBBytes = (unsigned char *)pixbuff;

  if ( jcprops.JPGChannels == 3 )
  {
    jcprops.DIBColor = IJL_RGB;
    jcprops.JPGColor = IJL_YCBCR;
    jcprops.JPGSubsampling = IJL_411;
    jcprops.DIBSubsampling = (IJL_DIBSUBSAMPLING) 0;
  }
  else
  {
    jcprops.DIBColor = IJL_G;
    jcprops.JPGColor = IJL_G;
    jcprops.JPGSubsampling = (IJL_JPGSUBSAMPLING) 0;
    jcprops.DIBSubsampling = (IJL_DIBSUBSAMPLING) 0;
  }

  if ( ijlRead(&jcprops, mode) != IJL_OK )
  {
    ijlFree(&jcprops);
    return 0;
  }

  if ( ijlFree(&jcprops) != IJL_OK ) return 0;

  return (void *)pixbuff;
}


void * Jpeg::Compress(const void *source,
                      int width,
                      int height,
                      int bpp,
                      int &len,
                      int quality)
{
  JPEG_CORE_PROPERTIES jcprops;
  jcprops.jprops.processor_type = IJL_PENTIUM_III_PROC;
  jcprops.jprops.upsampling_type = IJL_TRIANGLE_FILTER;

  if ( ijlInit(&jcprops) != IJL_OK )
  {
    ijlFree(&jcprops);
    return false;
  }

  jcprops.DIBWidth    = width;
  jcprops.DIBHeight   = -height;
  jcprops.JPGWidth    = width;
  jcprops.JPGHeight   = height;
  jcprops.DIBBytes    = (unsigned char *) source;
  jcprops.DIBPadBytes = 0;
  jcprops.DIBChannels = bpp;
  jcprops.JPGChannels = bpp;

  if ( bpp == 3 )
  {
    jcprops.DIBColor = IJL_BGR;
    jcprops.JPGColor = IJL_YCBCR;
    jcprops.JPGSubsampling = IJL_422;
    jcprops.DIBSubsampling = (IJL_DIBSUBSAMPLING) 0;
  }
  else
  {
    jcprops.DIBColor = IJL_G;
    jcprops.JPGColor = IJL_G;
    jcprops.JPGSubsampling = (IJL_JPGSUBSAMPLING) 0;
    jcprops.DIBSubsampling = (IJL_DIBSUBSAMPLING) 0;
  }

  int size = width*height*bpp;

  unsigned char * buffer = new unsigned char[size];

  jcprops.JPGSizeBytes = size;
  jcprops.JPGBytes     = buffer;

  jcprops.jquality = quality;


  IJLERR errWrite = ijlWrite(&jcprops,IJL_JBUFF_WRITEWHOLEIMAGE);
  if ( errWrite != IJL_OK )
  {
    ijlFree(&jcprops);
    delete buffer;
    return 0;
  }


  if ( ijlFree(&jcprops) != IJL_OK )
  {
    delete buffer;
    return 0;
  }

  len = jcprops.JPGSizeBytes;
  return buffer;
}



By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
ETA
Software Developer (Senior)
Netherlands Netherlands
I'm a 31 year old full-time programmer ('76).
(Currently: Lead Software System Designer)

Comments and Discussions