rendered paste body#include "PhotoBox.h"// C'tor.PhotoBox::PhotoBox(){ mpScreen = NULL; mbDone = false; mbWritten = false; mX = 0; // just test var. mpPhotoStrip = new PhotoStrip(this); mpTimer = new PhotoTimer(); }// D'tor.PhotoBox::~PhotoBox(){ TTF_Quit();}int PhotoBox::ResizeWindow(int iWidth, int iHeight){ return 0; /* Height / width ration */ GLfloat ratio; /* Protect against a divide by zero */ if ( iHeight == 0 ) iHeight = 1; ratio = ( GLfloat )iWidth / ( GLfloat )iHeight; /* Setup our viewport. */ glViewport( 0, 0, ( GLsizei )iWidth, ( GLsizei )iHeight ); /* change to the projection matrix and set our viewing volume. */ glMatrixMode( GL_PROJECTION ); glLoadIdentity( ); /* Set our perspective */ gluPerspective( 45.0f, ratio, 0.1f, 100.0f ); /* Make sure we're chaning the model view and not the projection */ glMatrixMode( GL_MODELVIEW ); /* Reset The View */ glLoadIdentity( ); return (1);}/** * Setup SDL * * @version 0.1 [2006.10.07] */bool PhotoBox::Init(){ if (!InitSDL()) return (false); if(TTF_Init()==-1) return (false); mpDebugFont = TTF_OpenFont("gill.ttf", 13); if (mpDebugFont == NULL) { char *msg = TTF_GetError(); int i = 0; } //InitConsole(); InitPhotoStrip(); //if (!InitCamera()) // return (false); //if (!InitOpenGL()) // return (false); return (true);}bool PhotoBox::InitPhotoStrip(){ mpPhotoStrip->Init(); return (true);}// Initialize OpenGLbool PhotoBox::InitOpenGL(){ // Sets up OpenGL double buffering SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1 ); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); glViewport(0,0, SCREEN_WIDTH, SCREEN_HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,1,0,1,0,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glEnable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); // Really Nice Perspective Calculations //glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); //ResizeWindow(SCREEN_WIDTH, SCREEN_HEIGHT); return (true);}// Initialize SDLbool PhotoBox::InitSDL(){ int result = 0; // Initialize SDL's subsystems - in this case, only video. if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0 ) { fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); // Start the timer after SDL_INIT_TIMER has been given to SDL_Init() mpTimer->Start(); // Video flag info. int videoFlags = 0; //videoFlags |= SDL_OPENGL; // Store the palette in hardware videoFlags |= SDL_HWPALETTE; // Enable window resizing videoFlags |= SDL_RESIZABLE; //videoFlags |= SDL_FULLSCREEN; // Get information from the videoinfo. const SDL_VideoInfo *videoInfo; videoInfo = SDL_GetVideoInfo( ); if ( !videoInfo ) { fprintf( stderr, "Video query failed: %s\n", SDL_GetError( ) ); return (false); } // HW supported? if ( videoInfo->hw_available ) videoFlags |= SDL_HWSURFACE | SDL_DOUBLEBUF; else videoFlags |= SDL_SWSURFACE; // This checks if hardware blits can be done if ( videoInfo->blit_hw ) videoFlags |= SDL_HWACCEL; // Create the main sdl surface mpScreen = SDL_SetVideoMode( SCREEN_WIDTH ,SCREEN_HEIGHT ,SCREEN_BPP ,videoFlags ); if ( mpScreen == NULL ) { return (false); } return (true);}bool PhotoBox::InitConsole(){ SDL_Rect Con_rect; // STEP 1: Init the consoles Con_rect.x = Con_rect.y = 20; Con_rect.w = Con_rect.h = 300; mpConsole = CON_Init( ".\\ConsoleFont.bmp" ,mpScreen ,10 // Number of lines ,Con_rect ); if (mpConsole == NULL) return (false); return (true);}// Initialize the camera using ARToolkitbool PhotoBox::InitCamera(){ // Initialize the ARToolKit video subsystem int result = 0; char *vconf = "camera.xml"; result = arVideoOpen(vconf); if (result == -1) { return (false); } // This function returns the size of the captured video frame, in pixels. result = arVideoInqSize( &mDim[0], &mDim[1] ); if (result == -1) { return (false); } // Start capturing. result = arVideoCapStart(); if (result == -1) { return (false); } mTexBuf = new unsigned char[mDim[0] * mDim[1] * 3]; // Create a video surface for the camera Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0x00ff0000; gmask = 0x0000ff00; bmask = 0xff000000; amask = 0x000000ff; #else rmask = 0x00ff0000; gmask = 0x0000ff00; bmask = 0x000000ff; amask = 0xff000000; #endif mpVideoSurface = SDL_CreateRGBSurface( SDL_HWSURFACE ,mDim[0] // width ,mDim[1] ,32 ,rmask ,gmask ,bmask ,amask ); return (true);}// Handle a console commandvoid PhotoBox::CommandHandler(ConsoleInformation *pConsole, char* pCommand) { }// Render a camera frame.void PhotoBox::RenderCamera(){ ARUint8* buffer = NULL; buffer = arVideoGetImage(); static unsigned char** ss_rows; if (buffer != NULL) { int y_offset = 0; unsigned char c; int pixel = 0; for (int y = 0; y < mDim[1]; ++y) { y_offset = y * mDim[0] * 3; for (int x = 0; x < mDim[0]; ++x) { // The << 2 multiplies the position by 4 moving // it to the correct location of the Uint8 buffer. c = buffer[ (((y) * mDim[0]+(x)) << 2) + 0]; mTexBuf[y_offset + x * 3 + 0] = c; c = buffer[ (((y) * mDim[0]+(x)) << 2) + 1]; mTexBuf[y_offset + x * 3 + 1] = c; c = buffer[ (((y) * mDim[0]+(x)) << 2) + 2]; mTexBuf[y_offset + x * 3 + 2] = c; } } if (!mbWritten) { WritePNG("test.png",mTexBuf, mDim[0], mDim[1]);// LOG("Image written.\n"); mbWritten = true; } // Draw the image to the screen SDL_Rect dstrect; //mpVideoSurface->pixels = mTexBuf; mpVideoSurface->pixels = buffer; dstrect.x = (mpScreen->w-mpVideoSurface->w)/2; dstrect.y = (mpScreen->h-mpVideoSurface->h)/2; dstrect.w = mpVideoSurface->w; dstrect.h = mpVideoSurface->h; if ( SDL_BlitSurface(mpVideoSurface, NULL, mpScreen, &dstrect) < 0 ) { SDL_FreeSurface(mpVideoSurface); } } arVideoCapNext();}SDL_Surface *PhotoBox::CreateCompatibleSurface( int width, int height ){ SDL_Surface *screen = SDL_GetVideoSurface(); SDL_PixelFormat *PixelFormat = screen->format; int flags = (screen->flags & SDL_HWSURFACE); SDL_Surface *surf; surf = SDL_CreateRGBSurface( flags, width, height, PixelFormat->BitsPerPixel, PixelFormat->Rmask, PixelFormat->Gmask, PixelFormat->Bmask, PixelFormat->Amask ); if ( !surf ) return NULL; if ( PixelFormat->palette && surf->format->palette ) { memcpy( surf->format->palette->colors, PixelFormat->palette->colors, PixelFormat->palette->ncolors*sizeof(SDL_Color) ); surf->format->palette->ncolors = PixelFormat->palette->ncolors; } return surf; }// Helper function which writes a PNG image from a RGB color array.int PhotoBox::WritePNG(char *fn, unsigned char *raster, unsigned int w, unsigned int h){ FILE *fp; png_structp png; png_infop info; png_bytepp row_pointers; int i; /* create file */ fp = fopen (fn, "wb"); if (!fp) { // xe_msg (1, "Can not create %s:\n%s", fn, syserrstr()); return (-1); } /* build list of pointers to each row */ row_pointers = (png_bytepp) malloc (h * sizeof(png_bytep)); if (!row_pointers) { // xe_msg (1, "Can not malloc %d PNG row pointers", h); fclose (fp); return (-1); } for (i = 0; i < h; i++) row_pointers[i] = raster + i*(w*3); /* write png */ png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info = png_create_info_struct (png); if (setjmp (png_jmpbuf (png))) { // xe_msg (1, "PNG error"); png_destroy_write_struct (&png, &info); free (row_pointers); fclose (fp); return (-1); } png_init_io(png, fp); png_set_IHDR ( png // png struct pointer ,info // header info ,w // width ,h // height ,8 // bit depth ,PNG_COLOR_TYPE_RGB // color_type ,PNG_INTERLACE_NONE // interlace type ,PNG_COMPRESSION_TYPE_DEFAULT // compresssion type ,PNG_FILTER_TYPE_DEFAULT // filter type ); png_write_info (png, info); png_write_image (png, row_pointers); png_write_end (png, info); png_destroy_write_struct (&png, &info); free (row_pointers); /* check for io error */ if (ferror(fp)) { // xe_msg (1, "Write error %s:\n%s", fn, syserrstr()); fclose (fp); return (-1); } /* ok */ fclose (fp); return (0);}/*bool PhotoBox::ReadPNG (const char *filename,char **data, unsigned int *width, unsigned int *height){ unsigned char png_sig[PNG_SIG_SIZE]; FILE *file; int sig_bytes; png_struct *png; png_info *info; bool status; file = fopen (filename, "r"); if (!file) return (false); //if (!openImageFile (filename, NULL, &file)) //return false; sig_bytes = fread (png_sig, 1, PNG_SIG_SIZE, file); if (png_check_sig (png_sig, sig_bytes) == 0) { fclose (file); return false; } png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png) return false; info = png_create_info_struct (png); if (info == NULL) { png_destroy_read_struct (&png, NULL, NULL); fclose (file); return false; } png_init_io (png, file); png_set_sig_bytes (png, sig_bytes); status = ReadPNGData (png, info, data, width, height); png_destroy_read_struct (&png, &info, NULL); fclose (file); return status;}*/bool PhotoBox::ReadPNG(const char * name, int * xres, int * yres, unsigned char **imgdata) { FILE * ifp; png_structp png_ptr; png_infop info_ptr; png_bytep *row_pointers; int x, y; /* Create and initialize the png_struct with the default error handlers */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { return false; /* Could not initialize PNG library, return error */ } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return false; /* Could not initialize PNG library, return error */ } /* open input file before doing any more PNG decompression setup */ if ((ifp = fopen(name, "rb")) == NULL) return false; /* Could not open image, return error */ /* Set error handling for setjmp/longjmp method of libpng error handling */ if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); /* If we get here, we had a problem reading the file */ fclose(ifp); return false; /* Could not open image, return error */ } /* Set up the input control if you are using standard C streams */ png_init_io(png_ptr, ifp); /* one-shot call to read the whole PNG file into memory */ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_ALPHA, NULL); *xres = png_get_image_width(png_ptr, info_ptr); *yres = png_get_image_height(png_ptr, info_ptr); /* copy pixel data into our own data structures */ row_pointers = png_get_rows(png_ptr, info_ptr); *imgdata = (unsigned char *) malloc(3 * (*xres) * (*yres)); if ((*imgdata) == NULL) { return false; } for (y=0; y<(*yres); y++) { unsigned char *img = &(*imgdata)[(y * (*xres) * 3)]; for (x=0; x<(*xres); x++) { img[(x*3) ] = row_pointers[(*yres) - y - 1][x ]; img[(x*3) + 1] = row_pointers[(*yres) - y - 1][x + 1]; img[(x*3) + 2] = row_pointers[(*yres) - y - 1][x + 2]; } } /* clean up after the read, and free any memory allocated - REQUIRED */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); fclose(ifp); /* Close the input file */ return true; /* No fatal errors */}// Created by Diederickbool PhotoBox::GetPNGImageSize(const char *file, int *width, int *height){ FILE * ifp; png_structp png_ptr; png_infop info_ptr; png_bytep *row_pointers; int x, y; /* Create and initialize the png_struct with the default error handlers */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { return false; /* Could not initialize PNG library, return error */ } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return false; /* Could not initialize PNG library, return error */ } /* open input file before doing any more PNG decompression setup */ if ((ifp = fopen(file, "rb")) == NULL) return false; /* Could not open image, return error */ /* Set error handling for setjmp/longjmp method of libpng error handling */ if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); /* If we get here, we had a problem reading the file */ fclose(ifp); return false; /* Could not open image, return error */ } /* Set up the input control if you are using standard C streams */ png_init_io(png_ptr, ifp); /* one-shot call to read the whole PNG file into memory */ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_ALPHA, NULL); *width = png_get_image_width(png_ptr, info_ptr); *height = png_get_image_height(png_ptr, info_ptr); return (true);}bool PhotoBox::ReadPNGData (png_struct *png, png_info *info, char **data, unsigned int *width, unsigned int *height){ png_uint_32 png_width, png_height; int depth, color_type, interlace, i; unsigned int pixel_size; png_byte **row_pointers; png_read_info (png, info); png_get_IHDR (png, info, &png_width, &png_height, &depth, &color_type, &interlace, NULL, NULL); *width = png_width; *height = png_height; /* convert palette/gray image to rgb */ if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb (png); /* expand gray bit depth if needed */ if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8) png_set_gray_1_2_4_to_8 (png); /* transform transparency to alpha */ if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha (png); if (depth == 16) png_set_strip_16 (png); if (depth < 8) png_set_packing (png); /* convert grayscale to RGB */ if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb (png); if (interlace != PNG_INTERLACE_NONE) png_set_interlace_handling (png); png_set_bgr (png); png_set_filler (png, 0xff, PNG_FILLER_AFTER);// png_set_read_user_transform_fn (png, premultiplyData); png_read_update_info (png, info); pixel_size = 4; *data = (char *) malloc (png_width * png_height * pixel_size); if (*data == NULL) return false; row_pointers = (png_byte **) malloc (png_height * sizeof (char *)); if (!row_pointers) { free (*data); return false; } for (i = 0; i < png_height; i++) row_pointers[i] = (png_byte *) (*data + i * png_width * pixel_size); png_read_image (png, row_pointers); png_read_end (png, info); free (row_pointers); return true;}/** * Execute the main loop, and capture events. * * @version 0.1 [2006.10.07] */int PhotoBox::Exec(){ while (!mbDone) { // Poll for events, and handle the ones we care about. SDL_Event event; while (SDL_PollEvent(&event)) { // Handle input if the console is used. switch (event.type) { case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_UP) { this->mpPhotoStrip->NextPhoto(); break; } else if (event.key.keysym.sym == '`') { /* Show/Hide consoles if(CON_isVisible( mpConsole )) CON_Hide(mpConsole ); else { CON_Topmost(mpConsole); SDL_EnableKeyRepeat(250,30); CON_Show(mpConsole ); } */ } case SDL_KEYUP: // If escape is pressed, return (and thus, quit) if (event.key.keysym.sym == SDLK_ESCAPE) return 0; break; case SDL_QUIT: { ShutDown(); mbDone = true; break; } } } // Render stuff Render(); //CON_DrawConsole(mpConsole); SDL_UpdateRect(mpScreen, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); } return(1);}/** * Renders the screen. * * @version 0.1 [2006.10.07] */void PhotoBox::Render(){// glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );// DisplayBMP("image.bmp");// RenderCamera(); mpPhotoStrip->RenderPhoto(); ShowDebugMessage(); //SDL_GL_SwapBuffers();}void PhotoBox::ShowDebugMessage(){ if (this->mDebugMSG.size() == 0) return; // Render some text in solid black to a new surface // then blit to the upper left of the screen // then free the text surface //SDL_Surface *screen; SDL_Color color={0,255,0}; SDL_Surface *text_surface; if(!(text_surface=TTF_RenderText_Solid(this->mpDebugFont,this->mDebugMSG.c_str(),color))) { //handle error here, perhaps print TTF_GetError at least int i = 0; } else { SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = 500; rect.h = 20; //SDL_BlitSurface(mpScreen,&rect,mpScreen,&rect); if (mpScreen != NULL) SDL_FillRect(mpScreen,&rect, 0x00000000); SDL_BlitSurface(text_surface,&rect,mpScreen,&rect);// SDL_UpdateRects(mpScreen, 1, &rect); //SDL_UpdateRect(mpScreen,0,0,SCREEN_WIDTH,SCREEN_HEIGHT); //perhaps we can reuse it, but I assume not for simplicity. SDL_FreeSurface(text_surface); }}void PhotoBox::Debug(std::string sMSG){ mDebugMSG = sMSG;}/** * Shuts down SDL, OGLConsole, OpenGL * * @version 0.1 [2006.10.07] */void PhotoBox::ShutDown(){ // Cleanup SDL SDL_Quit( ); mpScreen = NULL;} // From SDL documentation, for testing purpose.void PhotoBox::DisplayBMP(char *pFile){ SDL_Surface *image; /* Load the BMP file into a surface */ image = SDL_LoadBMP(pFile); if (image == NULL) { fprintf(stderr, "Couldn't load %s: %s\n", pFile, SDL_GetError());// LOG("File error"); return; } /* Blit onto the screen surface */ if(SDL_BlitSurface(image, NULL, mpScreen, NULL) < 0) fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); SDL_UpdateRect(mpScreen, 0, 0, image->w, image->h); /* Free the allocated BMP surface */ SDL_FreeSurface(image);}