Пример #1
0
void preparaletras()
{
    BMP* bmp, * nbmp;
    int i;

    for(i = 0; i < 3; i++)
    {
        char ca[10];
        snprintf(ca, sizeof(ca), "OUT%d.bmp", i);
        bmp = BMP_ReadFile(ca);
        bmp = BMP_Gray(bmp);
        nbmp = BMP_Resized(bmp, 20);
        BMP_WriteFile(nbmp, ca);
        BMP_ExtraiEntradas(nbmp, "entradaletras.txt");
        BMP_Free( bmp );
        BMP_Free( nbmp );
    }

    for(i = 3; i < 7; i++)
    {
        char ca[10];
        snprintf(ca, sizeof(ca), "OUT%d.bmp", i);
        bmp = BMP_ReadFile(ca);
        bmp = BMP_Gray(bmp);
        nbmp = BMP_Resized(bmp, 20);
        BMP_WriteFile(nbmp, ca);
        BMP_ExtraiEntradas(nbmp, "entradanumeros.txt");
        BMP_Free( bmp );
        BMP_Free( nbmp );
    }
}
Пример #2
0
void CMainFrame::OnViewScreenshotClipboard() 
{
	if (Model_Loaded())
	{
		CWaitCursor wait;

		// slightly iffy here, I'm going to assume that the rendering context is still valid from last time.
		// I can't do much else because I need to supply DC shit that I don't have in order to issue an OnDraw
		//	command to do it legally, so f**k it...
		//
		gbTextInhibit = AppVars.bCleanScreenShots;	//true;
		{
			ModelList_Render( g_iScreenWidth, g_iScreenHeight );	// render to back buffer

			ScreenShot(NULL,va("(C) Raven Software %s",GetYearAsString()));
		}
		gbTextInhibit = false;		

		void *pvDIB;
		int iBytes;
		if (BMP_GetMemDIB(pvDIB, iBytes))
		{
			ClipBoard_SendDIB(pvDIB, iBytes);
		}
		BMP_Free();
	}

	m_splitter.Invalidate(false);
}
Пример #3
0
// Unload images and textures
terrain::~terrain()
{
	// Delete the texture
	glDeleteTextures(1, &texture_handle);
	// Free the memory for the height map
	BMP_Free(heightmap);
	// Delete the display list if neccessary
	if (glIsList(dl_handle))
		glDeleteLists(dl_handle, 1);
}
Пример #4
0
void CMainFrame::OnViewScreenshotFile() 
{
	if (Model_Loaded())
	{
		CWaitCursor wait;

		// slightly iffy here, I'm going to assume that the rendering context is still valid from last time.
		// I can't do much else because I need to supply DC shit that I don't have in order to issue an OnDraw
		//	command to do it legally, so f**k it...
		//
		gbTextInhibit = AppVars.bCleanScreenShots;	//true;
		{
			ModelList_Render( g_iScreenWidth, g_iScreenHeight );	// render to back buffer
				
			// generate a filename...
			//
			char sBaseName[MAX_PATH];
			sprintf(sBaseName, Filename_WithoutPath(Filename_PathOnly(Model_GetFullPrimaryFilename())));
			//
			// look for a numbered slot to snapshot to...
			//
			#define NUM_SAVE_SLOTS 1000
			for (int iName=0; iName<NUM_SAVE_SLOTS; iName++)
			{
				char sFilename[MAX_PATH];

				if (iName==NUM_SAVE_SLOTS)
				{
					ErrorBox(va("Couldn't find a free save slot! (tried %d slots)",NUM_SAVE_SLOTS));
				}

				sprintf(sFilename, "c:\\%s_%03d.bmp",sBaseName,iName);

				if (!FileExists(sFilename))
				{
					ScreenShot(sFilename,va("(C) Raven Software %s",GetYearAsString()));					
					BMP_Free();
					break;
				}
			}
		}
		gbTextInhibit = false;
	}
	else
	{
		ErrorBox("No model loaded to work out path from!\n\n( So duhhhh... why try to take a snapshot? )");
	}

	m_splitter.Invalidate(false);
}
Пример #5
0
/* Creates a negative image of the input bitmap file */
int main( int argc, char* argv[] )
{
	UCHAR	r, g, b;
	UINT	width, height;
	UINT	x, y;
	BMP*	bmp;

	/* Check arguments */
	if ( argc != 3 )
	{
		fprintf( stderr, "Usage: %s <input file> <output file>\n", argv[ 0 ] );
		return 0;
	}

	/* Read an image file */
	bmp = BMP_ReadFile( argv[ 1 ] );
	BMP_CHECK_ERROR( stdout, -1 );

	/* Get image's dimensions */
	width = BMP_GetWidth( bmp );
	height = BMP_GetHeight( bmp );

	/* Iterate through all the image's pixels */
	for ( x = 0 ; x < width ; ++x )
	{
		for ( y = 0 ; y < height ; ++y )
		{
			
			/* Get pixel's RGB values */
			BMP_GetPixelRGB( bmp, x, y, &r, &g, &b );

			/* Invert RGB values */
			BMP_SetPixelRGB( bmp, x, y, 255 - r, 255 - g, 255 - b );
		}
	}

	/* Save result */
	BMP_WriteFile( bmp, argv[ 2 ] );
	BMP_CHECK_ERROR( stdout, -2 );


	/* Free all memory allocated for the image */
	BMP_Free( bmp );

	return 0;
}
Пример #6
0
// Load a texture and store its handle in "handle"
bool terrain::load_texture(const char *filename, GLuint *handle)
{
	BMP *bitmap;

	// Load the texture by reading a bmp file
	bitmap = BMP_ReadFile(filename);

	// Return false and show an error message if the file
	// could not be loaded
	if (BMP_GetError() != BMP_OK) {
		std::cout<<BMP_GetErrorDescription()<<std::endl;
		return false;
	}

	// Get a pointer to the bitmap data
	unsigned char* data = BMP_GetImageData(bitmap);

	// Generate one texture and store its ID in "handle"
	glGenTextures(1, handle);
	// Bind the texture
	glBindTexture(GL_TEXTURE_2D, *handle);
	// Enable linear blending between different mipmapping levels
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	// Clamp the texture at the borders
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	// Transfer the image data to the graphics card.
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BMP_GetWidth(bitmap), BMP_GetHeight(bitmap), 0, GL_RGB, GL_UNSIGNED_BYTE, data);	

	// Not needed anymore
	free(data);
	BMP_Free(bitmap);

	// Unbind texture
	glBindTexture(GL_TEXTURE_2D, 0);

	return true;
}
Пример #7
0
/* Creates a blur image of the input bitmap file */
int main( int argc, char* argv[] )
{
	UCHAR	r, g, b;
	UINT	width, height;
	UINT	x, y;
	BMP*	bmp;
	BMP*	bmp_new;
	int 	size;
	int 	count;
	int     i, k, start_i, stop_i, start_k, stop_k;
	int 	r_sum, g_sum, b_sum;
	UCHAR	r_new, g_new, b_new;

	/* Check arguments */
	if ( argc != 4 )
	{
		fprintf( stderr, "Usage: %s <input file> <output file> <blur box size>\n", argv[ 0 ] );
		return 0;
	}

	size = atoi(argv[3]);
	if (size <= 0){
		printf("Please enter a positive integer as the blur box size argument.\n");
		return 0;
	}

	/* Read an image file */
	bmp = BMP_ReadFile( argv[ 1 ] );
	BMP_CHECK_ERROR( stdout, -1 );
	bmp_new = BMP_ReadFile( argv[ 1 ] );
	BMP_CHECK_ERROR( stdout, -1 );

	/* Get image's dimensions */
	width = BMP_GetWidth( bmp );
	height = BMP_GetHeight( bmp );

	/* Iterate through all the image's pixels */
	for ( x = 0 ; x < width ; ++x )
	{
		for ( y = 0 ; y < height ; ++y )
		{
			r_sum = 0;
			g_sum = 0;
			b_sum = 0;
			count = 0;
			/* Get pixel's RGB values */
			start_i = x - size;
			stop_i = x + size;
			start_k = y - size;
			stop_k = y + size;
			for (i = start_i; i <= stop_i; i++){
				for (k = start_k; k <= stop_k; k++){
					if ((i >= 0) && (i < width) && (k >= 0) && (k < height)){
						BMP_GetPixelRGB(bmp, i, k, &r, &g, &b);
						count++;
						r_sum = r_sum + r;
						g_sum = g_sum + g;
						b_sum = b_sum + b;
					}
				}
			}
			r_new = r_sum / count;
			g_new = g_sum / count;
			b_new = b_sum / count;

			/* Invert RGB values */
			BMP_SetPixelRGB( bmp_new, x, y, r_new, g_new, b_new );
		}
	}

	/* Save result */
	BMP_WriteFile( bmp_new, argv[ 2 ] );
	BMP_CHECK_ERROR( stdout, -2 );


	/* Free all memory allocated for the image */
	BMP_Free( bmp );
	BMP_Free( bmp_new );

	return 0;
}
Пример #8
0
void CModViewView::OnTimer(UINT nIDEvent) 
{
	if (nIDEvent != th_100FPS)
	{
		CView::OnTimer(nIDEvent);
		return;
	}
	

	// otherwise, it's one of our timer events, so...


	{ // new bit, poll the remote control stuff 10 times per second (it's also done in OnIdle(), but that's not always fast enough when animating)
		static	float fTime = 0.0f;
				float fTimeNow = GetFloatTime();

		#define UPDATE_FRAMES_PER_SECOND 10.0f

		if (fTimeNow - fTime > 1.0f/UPDATE_FRAMES_PER_SECOND)
		{
			fTime = fTimeNow;
//			OutputDebugString(va("Time = %f seconds\n",GetFloatTime()));

			if (WinTalk_HandleMessages())
			{
				// app exit requested
				AppVars.bAnimate = qfalse;	// groan... stop the animation so the app doesn't spend all it's time
											//				in the render loop. This allows the App::OnIdle() version
											//				of the Wintalk_HandleMessages() handler to get a look in,
											//				and therefore spot that an exit is being requested.
			}
		}
	}

//	if (!DraggingMouse()) 
	{
		if (ModelList_Animation())
		{
			// one or more models have updated frames (or lerping)...
			//
			Invalidate(false);
		}
	}


	if (Gallery_Active())
	{
		extern bool gbInRenderer;
		if (!gbInRenderer)
		{
			static bool bAlreadyHere = false;
			if (!bAlreadyHere)	// jic.
			{
				bAlreadyHere = true;

				extern int giRenderCount;
				static CString strCaption;
				static CString strScript;

				static bool bSnapshotTakingPlace = false;
				if (!bSnapshotTakingPlace)
				{				
					int iRemainingPlusOne = GalleryRead_ExtractEntry(strCaption, strScript);
					if (iRemainingPlusOne)	// because 0 would be fail/empty
					{
						giGalleryItemsRemaining = iRemainingPlusOne-1;
						StatusMessage( va("( Gallery: %d remaining )", giGalleryItemsRemaining) );
						OutputDebugString(va("\"%s\" (script len %d)\n",(LPCSTR)strCaption,strScript.GetLength()));

						strScript += "\n";			

						string strOutputFileName( va("%s\\%s",scGetTempPath(),"temp.mvs") );
							
						int iReturn = SaveFile(strOutputFileName.c_str(),(LPCSTR)strScript, strScript.GetLength());
						if (iReturn != -1)
						{
							extern bool Document_ModelLoadPrimary(LPCSTR psFilename);
							if (Document_ModelLoadPrimary(strOutputFileName.c_str()))
							{
								if (Model_Loaded())
								{
									ModelHandle_t hModel = AppVars.Container.hModel;

									Model_Sequence_Lock( hModel, Gallery_GetSeqToLock(), true, false);
								}

								giRenderCount = 0;
								bSnapshotTakingPlace = true;
							}
						}
					}
					else
					{
						// all done...
						//
						gbTextInhibit = false;
						Gallery_Done();
						StatusMessage( NULL );
						//
						// report...
						//
						CString strReport;

						if (!strGalleryErrors.IsEmpty())
						{
							strReport += "====================== Errors: ===================\n\n";
							strReport += strGalleryErrors;
							strReport += "\n\n";
						}

						if (!strGalleryWarnings.IsEmpty())
						{
							strReport += "====================== Warnings: ===================\n\n";
							strReport += strGalleryWarnings;
							strReport += "\n\n";
						}

						if (!strGalleryInfo.IsEmpty())
						{
							strReport += "====================== Info: ===================\n\n";
							strReport += strGalleryInfo;
							strReport += "\n\n";
						}

						if (!strReport.IsEmpty())
						{
							strReport.Insert(0,"The following messages appeared during gallery-snapshots....\n\n");
						}
						else
						{
							strReport = va("All gallery-snapshots done\n\nOutput dir was: \"%s\\n",Gallery_GetOutputDir());
						}

						SendStringToNotepad(strReport,"gallery_report.txt");
					}
				}
				else
				{
					if (giRenderCount == 2)	// ... so it's rendered to back buffer for snapshot, and front for user
					{	
						//
						// generate a filename...
						//				
						char sOutputFileName[MAX_PATH];
						CString strBaseName(strCaption);
						while (strBaseName.Replace("\t"," "));
						while (strBaseName.Replace("  "," "));
						sprintf(sOutputFileName, "%s\\%s.bmp",Gallery_GetOutputDir(),strBaseName);
						ScreenShot(sOutputFileName,/*strCaption*/strBaseName);
						BMP_Free();			

						bSnapshotTakingPlace = false;	// trigger next snapshot
					}
					else
					{
						Invalidate(false);	// cause another screen update until render count satisfied
					}
				}

				bAlreadyHere = false;
			}
		}
	}
}
Пример #9
0
int separaletras (char * entrada)
{
    UCHAR	r, g, b;
    UINT	width, height;
    UINT	x, y;
    BMP*	bmp;
    BMP*	bmp_BW;
    int conta = 0;

    bmp = BMP_ReadFile( entrada );
    bmp_BW = BMP_ReadFile( entrada );
    BMP_CHECK_ERROR(stdout, -1);
    width = BMP_GetWidth( bmp );
    height = BMP_GetHeight( bmp );
    short Black_White[height][width];
    int colunaDaVez[height - 2*OFFSET_Y];
    int Coluna_Inicio = 0;
    int Coluna_Final  = 0;
    int Linha_Inicio  = 0;
    int Linha_Final   = 0;
    char nomeArquivo[20];

    for( x = 0 ; x < width ; ++x)
    {
        for( y = 0 ; y < height ; ++y)
        {
            BMP_GetPixelRGB( bmp, x, y, &r, &g, &b );
            if((r+g+b) < 384 )
            {
                Black_White[y][x] = 0;
                BMP_SetPixelRGB(bmp_BW, x, y, 0, 0, 0);
            }
            else
            {
                Black_White[y][x] = 1;
                BMP_SetPixelRGB(bmp_BW, x, y, 255, 255, 255);
            }
        }
    }

    for( x = 0 ; x < width ; x++)
    {
        for( y = 0 ; y < height ; y++ )
        {
            if(Black_White[y][x] != Black_White[y][x+1])
            {
                BMP_SetPixelRGB(bmp_BW, x, y, 0,0,0);
            }
            else
            {
                BMP_SetPixelRGB(bmp_BW, x, y, 255, 255, 255);
            }
            if(Black_White[y][x] != Black_White[y+1][x])
            {
                BMP_SetPixelRGB(bmp_BW, x, y, 0, 0, 0);
            }
        }
    }
    int c;
    int numeroArquivo = 0;
    int k,h;

    for( x = OFFSET_X ; x < width-OFFSET_X ; x++)
    {
        for(y = OFFSET_Y ; y < height-OFFSET_Y ; y++)
        {
            BMP_GetPixelRGB(bmp_BW, x, y, &r, &g, &b);

            if(r+g+b > 0)
            {
                colunaDaVez[y-OFFSET_Y] = 0;
            }
            else
            {
                colunaDaVez[y-OFFSET_Y] = 1;
            }
        }
        c = verificaColuna_BW(colunaDaVez, height-2*OFFSET_Y);

        if(c == 0 && Coluna_Inicio != 0)
        {
            sprintf(nomeArquivo, "OUT%d.bmp",numeroArquivo);
            Coluna_Final = x;
            for(k = OFFSET_Y; k < height-OFFSET_Y; k++)
            {
                for(h = Coluna_Inicio ; h < Coluna_Final ; h++)
                {
                    BMP_GetPixelRGB(bmp_BW, h, k, &r, &g, &b);
                    if(r+g+b > 0)
                    {
                        colunaDaVez[h - Coluna_Inicio] = 0;
                    }
                    else
                    {
                        colunaDaVez[h - Coluna_Inicio] = 1;
                    }
                }
                c = verificaColuna_BW(colunaDaVez, Coluna_Final-Coluna_Inicio);
                if(c == 0 && Linha_Inicio != 0)
                {
                    if(k-Linha_Inicio > 10)
                    {
                        Linha_Final = k;

                        BMP_Cut_and_Export(bmp, Coluna_Inicio, Coluna_Final, Linha_Final, Linha_Inicio, nomeArquivo);
                        conta++;
                        Coluna_Final = 0;
                        Coluna_Inicio = 0;
                        Linha_Inicio = 0;
                        Linha_Final = 0;
                        numeroArquivo++;
                        k = h = 200000;
                        break;
                    }
                    else
                    {
                        Linha_Inicio = k;
                    }
                }
                if(c == 1 && Linha_Inicio == 0)
                {
                    Linha_Inicio = k;
                }
            }
        }
        if(c == 1 && Coluna_Inicio == 0)
        {
            Coluna_Inicio = x;
        }

    }
    BMP_CHECK_ERROR( stdout, -1);
    BMP_Free(bmp);
    BMP_Free(bmp_BW);
    return conta;
}
Пример #10
0
// open 24-bit RGB file either to disk or memory
//
// if psFileName == NULL, open memory file instead
//
static bool BMP_Open(LPCSTR psFilename, int iWidth, int iHeight)
{
	BITMAPFILEHEADER BMPFileHeader;
	BITMAPINFOHEADER BMPInfoHeader;

	int iPadBytes	= (4-((iWidth * sizeof(RGBTRIPLE))%4))&3;
	int iWidthBytes =     (iWidth * sizeof(RGBTRIPLE))+iPadBytes;
		
	BMP_Free();
	fhBMP = NULL;
	
	if (psFilename)
	{
		extern void CreatePath (const char *path);
		CreatePath(psFilename);

		fhBMP = fopen(psFilename,"wb");
		if (!(int)fhBMP)
			return false;
	}
	else
	{
		iBMP_MallocSize = sizeof(BITMAPINFOHEADER) + (iWidthBytes * iHeight);
		pBMP = (PMEMORYBMP) malloc ( iBMP_MallocSize );
		if (!pBMP)
			return false;
	}

	memset(&BMPFileHeader, 0, sizeof(BITMAPFILEHEADER));
	BMPFileHeader.bfType=(WORD)('B'+256*'M');
//	int iPad= ((sizeof(RGBTRIPLE)*iWidth)%3)*iHeight;	
//	BMPFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(sizeof(RGBTRIPLE)*iWidth*iHeight);//+iPad;
	BMPFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(iWidthBytes * iHeight);

	BMPFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);	// No palette
	
	if (fhBMP)
	{
		fwrite	(&BMPFileHeader,sizeof(BMPFileHeader),1,fhBMP);
	}
	else
	{
		// memory version doesn't use the BITMAPFILEHEADER structure
	}

	memset(&BMPInfoHeader, 0, sizeof(BITMAPINFOHEADER));
	BMPInfoHeader.biSize=sizeof(BITMAPINFOHEADER);
	BMPInfoHeader.biWidth=iWidth;
	BMPInfoHeader.biHeight=iHeight;
	BMPInfoHeader.biPlanes=1;
	BMPInfoHeader.biBitCount=24;
	BMPInfoHeader.biCompression=BI_RGB; 
	BMPInfoHeader.biSizeImage=0;// BMPFileHeader.bfSize - (sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));	// allowed for BI_RGB bitmaps
	BMPInfoHeader.biXPelsPerMeter=0;	// don't know about these
	BMPInfoHeader.biYPelsPerMeter=0;
	BMPInfoHeader.biClrUsed=0;
	BMPInfoHeader.biClrImportant=0;

	if (fhBMP)
	{
		fwrite	(&BMPInfoHeader,sizeof(BMPInfoHeader),1,fhBMP);
	}
	else
	{
		pBMP->BMPInfoHeader = BMPInfoHeader;	// struct copy
		iBMP_PixelWriteOffset = 0;
	}

	return true;
}
Пример #11
0
/* Creates a negative image of the input bitmap file */
int main( int argc, char* argv[] )
{
	UCHAR	r, g, b;
    int pos = 0;
	int i = 0;
	int startPos = 0;
	int get_x = 0;
	int get_y = 0;
	int thread_num = 0;


    


	/* Check arguments */
	if ( argc != 5 )
	{
		fprintf( stderr, "Usage: %s <input file> <output file>\n", argv[ 0 ] );
		return 0;
	}
    
	/* Read an image file */
	bmp = BMP_ReadFile( argv[ 1 ] );
	BMP_CHECK_ERROR( stdout, -1 );
	/* Get image's dimensions */
	width = BMP_GetWidth( bmp );
	height = BMP_GetHeight( bmp );
	size = width*height;
	box_size = atoi(argv[3]);
	thread_num = atoi(argv[4]);

	if (box_size <= 0){
		printf("sorry, box size cannot be negative or 0\n");
		return 0;
	}

	if (thread_num <= 0){
		printf("sorry, thread number cannot be negative or 0\n");
		return 0;
	}
	interval = size/(thread_num-1);
	// printf("%d\n", size);
	pthread_t thread[thread_num];
	int inter[thread_num];

	/* Iterate through all the image's pixels */
	for ( get_x = 0 ; get_x < width ; get_x++ )
	{
		for ( get_y = 0 ; get_y < height ; get_y++ )
		{
			/* Get pixel's RGB values */
			BMP_GetPixelRGB( bmp, get_x, get_y, &r, &g, &b );

            pos = get_x + get_y*width;
            pixelsR[pos] = r;
            pixelsG[pos] = g;
            pixelsB[pos] = b;
			// BMP_SetPixelRGB( bmp, x, y, 255 - r, 255 - g, 255 - b );
		}
	}

	while (i < thread_num){ 
		inter[i] = startPos;
		i++;
		startPos = startPos + interval;
	}


    i = 0;
	while (i < thread_num){
		pthread_create(&thread[i], NULL, &blur, &inter[i]);
		i++;
	}
	


	i = 0;
	while (i < thread_num){
		pthread_join(thread[i], NULL);
		i++;
	}

	/* Save result */
	BMP_WriteFile( bmp, argv[ 2 ] );
	BMP_CHECK_ERROR( stdout, -2 );


	/* Free all memory allocated for the image */
	BMP_Free( bmp );

	return 0;
}
Пример #12
0
int main() {
    static const char* cubeNames[CC_FACE_NUM] = {
            "TOP.bmp",
            "LEFT.bmp",
            "FRONT.bmp",
            "RIGHT.bmp",
            "BACK.bmp",
            "DOWN.bmp"
    };

    struct cc_context ctx;

    unsigned int i = 0;
    unsigned int j = 0;

    unsigned char rr;
    unsigned char gg;
    unsigned char bb;

    BMP *bmpCube[CC_FACE_NUM];

    unsigned int   width  = 0;
    unsigned int   height = 0;
    unsigned short depth  = 0;

    BMP *output = NULL;

    unsigned int pano_width  = 0;
    unsigned int pano_height = 0;

    const struct cc_coord* coord = NULL;

    // Read the 6 input images
    for (i = 0; i < CC_FACE_NUM; ++i) {
        bmpCube[i] = BMP_ReadFile(cubeNames[i]);

        if (BMP_GetError() != BMP_OK) {
            return 1;
        }
    }

    // Get image's dimensions
    width  = (unsigned int)BMP_GetWidth( bmpCube[0]);
    height = (unsigned int)BMP_GetHeight(bmpCube[0]);
    depth  = BMP_GetDepth( bmpCube[0]);

    // The input images must be square
    if (width != height) {
        return 1;
    }

    /*
       Initialise the algorithm:
         the width of each input is 640 pixel,
         the vertical view portion is PI (180 degrees),
         the horizontal view portion is 2*PI (360 degress).

       In this case, the output image size will be calculated accordingly.
       There is another more detailed init function you can play with.
     */
    cc_init(&ctx, width, M_PI*2.0, M_PI);

    // Generate the mapping from panorama to cubic
    cc_gen_map(&ctx);

    // Access the dimension of the panorama image
    pano_width  = ctx.px_pano_h;
    pano_height = ctx.px_pano_v;

    // Create the panorama output image
    output = BMP_Create(pano_width, pano_height, depth);

    // Map the pixels from the panorama back to the source image
    for (i = 0; i < pano_width; ++i) {
        for (j = 0; j < pano_height; ++j) {
            // Get the corresponding position of (i, j)
            coord = cc_get_coord(&ctx, i, j);

            // Access the pixel
            BMP_GetPixelRGB(bmpCube[coord->face], (unsigned long)coord->x, (unsigned long)coord->y, &rr, &gg, &bb);

            // Write the pixel to the panorama
            BMP_SetPixelRGB(output, i, j, rr, gg, bb);
        }
    }

    // Write the output file
    BMP_WriteFile(output, "PANO.bmp");

    // Release memory
    BMP_Free(output);

    for (i = 0; i < CC_FACE_NUM; ++i) {
        BMP_Free(bmpCube[i]);
    }

    cc_close(&ctx);

    return 0;
}