stdr_msgs::LadybugImages::Ptr
separateImages(const unsigned char *packet, const ros::Time * stamp)
{
  stdr_msgs::LadybugImages::Ptr images( new stdr_msgs::LadybugImages );
  separateImages(*images, packet, stamp);
  return images;
}
stdr_msgs::LadybugImages::Ptr
separateImages(const sensor_msgs::Image & packet)
{
  stdr_msgs::LadybugImages::Ptr images( new stdr_msgs::LadybugImages );
  separateImages(*images, &(packet.data[0]), &packet.header.stamp);
  return images;
}
int main(int argc, char* argv[]){
    if(argc < 4){
        printHelp();
        exit(-1);  
    }
    
    char *imageType = argv[2]; //-sbs:sid-by-side or -ab:above/below
    
    // ----- Anaglyph conversion
    //TODO: simplify code with only one function call
    if(!strcmp(argv[3],"-e")){    
        printf("--- GREEN-MAGENTA ANAGLYPH CONVERSION  ---\n");
        IplImage *frame, *frameL, *frameR;        
        //load image
        //images are loaded by openCV with color channels in this order: BGR
        frame = cvLoadImage(argv[1], 1);
        
        //TEST PSNR FROM OPENCV CVT COLOR TO AND FROM RGB YCBCR
        /*CvSize Size = cvSize( frame->width, frame->height);
        IplImage *RGBtoYCbCr = cvCreateImage(Size, frame->depth, frame->nChannels);
        IplImage *YCbCrtoRGB = cvCreateImage(Size, frame->depth, frame->nChannels);
        cvCvtColor(frame, RGBtoYCbCr, CV_BGR2YCrCb);
        cvCvtColor(RGBtoYCbCr, YCbCrtoRGB, CV_YCrCb2BGR);
        cvSaveImage("RGB-YCbCr-RGB.bmp",YCbCrtoRGB);
        cvReleaseImage(&RGBtoYCbCr);
        cvReleaseImage(&YCbCrtoRGB);*/
        
        //Simple error handling
        if(!frame){
           printf("Error opening BMP file.");
           exit(-1);
        }            
        //some verifications regarding the image
        if(frame->width % 2 != 0){
              printf("Image width is not divisible by 2. Please, resize it!");
              exit(-1);
        }            
        int width = frame->width;
        int height = frame->height;      
            
        //get size of the two images from the stereo pair, based on its type
        CvSize size;
        if(!strcmp(imageType, "-sbs")){
            size = cvSize( width/2, height);
        }
        else if(!strcmp(imageType, "-ab")){
            size = cvSize( width, height/2);
        }
        else{
            printHelp();
            exit(-1);                    
        }
        
        //copy image properties
        frameL = cvCreateImage(size, frame->depth, frame->nChannels);
        frameR = cvCreateImage(size, frame->depth, frame->nChannels);
        cvZero(frameL);
        cvZero(frameR);
        
        //divide the stereo pair into two images
        separateImages(frame, &frameL, &frameR, width, height, imageType);
                
        //create anaglyph
        createAnaglyph(argv[1],frameL, frameR);  
                
        cvReleaseImage(&frame);
        cvReleaseImage(&frameL);
        cvReleaseImage(&frameR);
        printf("--- ANAGLYPH CONVERSION SUCCESSFULLY COMPLETED! ---\n");
    }
    
    // ----- Anaglyph reversion
    else if(!strcmp(argv[3],"-d")){
        printf("--- ANAGLYPH TO STEREO PAIR REVERSION ---\n");
        reverseAnaglyph(argv[1], imageType);
        printf("--- ANAGLYPH REVERSION SUCCESSFULLY COMPLETED! ---\n");
    }
    else{
        printHelp();
        exit(-1);      
    }
    
    return 0;
}
void
separateImages(stdr_msgs::LadybugImages & images, const sensor_msgs::Image & packet)
{
  separateImages(images, &(packet.data[0]), &packet.header.stamp);
}
int main(int argc, char* argv[]){
    IplImage *frame, *frameL, *frameR, *anaglyph;
    CvCapture *capture = cvCreateFileCapture(argv[1]);
    int videoType = atoi(argv[2]); //0:sid-by-side or 1:above/below
    
    //Simple error handling
    if(!capture){
       printf("Erro ao abrir o video.");
       exit(-1);
    }
    
    //some verifications regarding the video
    frame = cvQueryFrame(capture);
    if(!frame){
        printf("Video vazio.");
        exit(-1);
    }
    if(frame->width % 2 != 0){
          printf("Video possui largura não divisível por 2. Favor cortar!");
          exit(-1);
    }
    
    //prepare anaglyph video
    double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
    CvSize videosize;
    switch(videoType){    
        case 0:
             videosize = cvSize(
                                      (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH)/2,
                                      (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT)
                                );
             break;
        case 1:
             videosize = cvSize(
                                      (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH),
                                      (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT)/2
                                );
             break;
        default:                
             printf("Command call: SBS-UB-to-anaglyph-video <side-by-side_video> 0|1\n0:side-by-side and 1:above/below");
             exit(-1);          
    }
    CvVideoWriter *writer = cvCreateVideoWriter("anaglyph-gray.avi",CV_FOURCC('H','F','Y','U'), fps, videosize);
    
    //start working on each frame
    while((frame = cvQueryFrame(capture)) != NULL){ 
        //get width and height from original image
        int width = frame->width;
        int height = frame->height;      
        
        //new images will have half width of original image
        CvSize size;
        switch(videoType){
            case 0:
                 size = cvSize( width/2, height);
                 break;
            case 1:
                 size = cvSize( width, height/2);
                 break;
            default:
                 printf("Command call: SBS-UB-to-anaglyph-video <side-by-side_video> 0|1\n0:side-by-side and 1:above/below");
                 exit(-1);                    
        }
        
        //copy image properties
        frameL = cvCreateImage(size, frame->depth, frame->nChannels);
        frameR = cvCreateImage(size, frame->depth, frame->nChannels);
        cvZero(frameL);
        cvZero(frameR);
        
        //divide frames in two
        separateImages(frame, &frameL, &frameR, width, height, videoType);           
        
        anaglyph = cvCreateImage(size, frameL->depth, frameL->nChannels);
        cvZero(anaglyph);
        
        //create anaglyph
        createAnaglyph(frameL, frameR, &anaglyph);
        
        //if any error occurr (f.e. segmentation fault, check if you have the codec installed)
        //Huffyuv codec (lossless): http://neuron2.net/www.math.berkeley.edu/benrg/huffyuv.html
        cvWriteFrame(writer, anaglyph);  
        
        cvReleaseImage(&frameL);
        cvReleaseImage(&frameR);
        cvReleaseImage(&anaglyph);
    }
        
    //free pointers  
    cvReleaseCapture(&capture);
    cvReleaseVideoWriter(&writer);
    
    return 0;
}