core/vidl_vil1/vidl_vil1_avicodec.cxx

Go to the documentation of this file.
00001 //:
00002 // \file
00003 
00004 #include "vidl_vil1_avicodec.h"
00005 #include <vidl_vil1/vidl_vil1_frame.h>
00006 #include <vidl_vil1/vidl_vil1_movie.h>
00007 
00008 #include <vcl_iostream.h>
00009 #include <vcl_cstdio.h>
00010 
00011 #include <vul/vul_file.h>
00012 
00013 // Microsoft files
00014 #include <windows.h>
00015 #include <vfw.h>
00016 #include <windowsx.h> // for _fmemset function
00017 
00018 
00019 // To improve performance, we could use a Look Up Table
00020 // instead of computing  255/32
00021 #define RGB16R(rgb)     ((((UINT)(rgb) >> 10) & 0x1F) * 255u / 31u)
00022 #define RGB16G(rgb)     ((((UINT)(rgb) >> 5)  & 0x1F) * 255u / 31u)
00023 #define RGB16B(rgb)     ((((UINT)(rgb) >> 0)  & 0x1F) * 255u / 31u)
00024 
00025 //-----------------------------------------------------------------------------
00026 vidl_vil1_avicodec::vidl_vil1_avicodec()
00027 {
00028   avi_get_frame_ = NULL;
00029   avi_stream_ = NULL;
00030   avi_file_ = NULL;
00031   encoder_type = ASKUSER;
00032   _fmemset(&opts, 0, sizeof(AVICOMPRESSOPTIONS));
00033   encoder_options_valid=false;
00034 }
00035 
00036 
00037 //-----------------------------------------------------------------------------
00038 vidl_vil1_avicodec::~vidl_vil1_avicodec()
00039 {
00040   if (avi_get_frame_)
00041     AVIStreamGetFrameClose(avi_get_frame_); //This needs to be done, but only after a reading.
00042   if (avi_stream_)
00043     AVIStreamRelease(avi_stream_);
00044   if (avi_file_)
00045     AVIFileRelease(avi_file_);
00046   AVIFileExit();
00047 }
00048 
00049 
00050 //-----------------------------------------------------------------------------
00051 bool vidl_vil1_avicodec::read_header()
00052 {
00053   AVIFileInfo(avi_file_, &avi_file_info_, sizeof(AVIFILEINFO));
00054   AVIStreamInfo(avi_stream_, &avi_stream_info_, sizeof(AVISTREAMINFO));
00055 
00056   //Read in Width
00057   set_width(avi_file_info_.dwWidth);
00058   if (avi_stream_info_.rcFrame.right != int(avi_file_info_.dwWidth)+avi_stream_info_.rcFrame.left)
00059   {
00060     vcl_cerr << "vidl_vil1_avicodec::read_header width size screwed up\n"
00061              << "          size of avi file : " << avi_file_info_.dwWidth
00062              << "\n          size of the stream : "
00063              << avi_stream_info_.rcFrame.right-avi_stream_info_.rcFrame.left
00064              << vcl_endl;
00065   }
00066 
00067   //Read in Height
00068   set_height(avi_file_info_.dwHeight);
00069   if (avi_stream_info_.rcFrame.bottom != int(avi_file_info_.dwHeight)+avi_stream_info_.rcFrame.top)
00070   {
00071     vcl_cerr << "vidl_vil1_avicodec::read_header Height size screwed up"
00072              << "\n          size of avi file : " << avi_file_info_.dwHeight
00073              << "\n          size of the stream : "
00074              << avi_stream_info_.rcFrame.bottom-avi_stream_info_.rcFrame.top
00075              << vcl_endl;
00076   }
00077 
00078   //Read in Length
00079   set_number_frames(avi_file_info_.dwLength);
00080 
00081   // treat as blocked even though it isn't
00082   //SetBlockSizeX(width());
00083   //SetBlockSizeY(height());
00084   //set_widthBlocks((int)((width()+GetBlockSizeX()-1)/GetBlockSizeX()));
00085   //set_heightBlocks((int)((height()+GetBlockSizeY()-1)/GetBlockSizeY()));
00086   return true;
00087 }
00088 
00089 //-----------------------------------------------------------------------------
00090 bool vidl_vil1_avicodec::write_header()
00091 {
00092    vcl_fprintf(stderr, "vidl_vil1_avicodec::write_header Not implemented.\n");
00093    return false;
00094 }
00095 
00096 
00097 //-----------------------------------------------------------------------------
00098 bool vidl_vil1_avicodec::get_section(
00099                                 int position, // position of the frame in the stream
00100                                 void* ib, // To receive the datas
00101                                 int x0, // starting x
00102                                 int y0, // starting y
00103                                 int xs, // row size
00104                                 int ys) const // col size
00105 {
00106   byte* DIB = (byte*) AVIStreamGetFrame(avi_get_frame_, position);
00107 
00108   WORD BitsPerPixel = ((LPBITMAPINFOHEADER)DIB)->biBitCount;
00109 #ifdef DEBUG
00110   vcl_cout << "Number of bits : " << BitsPerPixel << "  Number of bytes : " << get_bytes_pixel() << vcl_endl;
00111 
00112   WORD ColorsUsed = ((LPBITMAPINFOHEADER)DIB)->biClrUsed;
00113   vcl_cout << "Number of colors used : " << ColorsUsed << vcl_endl;
00114   if (ColorsUsed!=0) vcl_cout << "Not sure we can handle the stream if ColorsUsed!=0\n";
00115 #endif
00116 
00117   //For the moment
00118   if ((BitsPerPixel!=16) && (BitsPerPixel!=24))
00119   {
00120     vcl_cerr << "vidl_vil1_avicodec : Don't know how to process a "
00121              << BitsPerPixel<< " bits per pixel AVI File.\n";
00122     return false;
00123   }
00124 
00125   DIB += *(LPDWORD)DIB;
00126   byte* StartDIB = (byte*)DIB;
00127   // Size of a row in number of bytes in the DIB structure
00128   // (a row contains a multiple of 4 bytes)
00129   int line_length = (width()*BitsPerPixel+31)/32*4;
00130 
00131   if (!ib)
00132   {
00133     ib = new byte[xs*ys*get_bytes_pixel()];
00134     if (!ib) {
00135       //SetStatusBad();
00136       return false;
00137     }
00138   }
00139 
00140   byte* db = (byte*)ib; // current output data
00141 
00142   // Store the DIB datas into ib (db).
00143   // Note : DIB is a flipped upside down
00144   switch (BitsPerPixel)
00145   {
00146     case 24:
00147       for (int j=height()-y0-1; j>=height()-y0-ys; j--)
00148       {
00149         DIB = StartDIB+ (j*line_length)+x0*(BitsPerPixel/8);
00150         for (int i=0; i<xs; i++)
00151         {
00152           *db = *(DIB+2);
00153           *(db+1) = *(DIB+1);
00154           *(db+2) = *(DIB);
00155           db+=3;
00156           DIB+=3;
00157         }
00158       }
00159       break;
00160     case 16:
00161       for (int j=height()-y0-1; j>=height()-y0-ys; j--)
00162       {
00163         DIB = StartDIB + (j*line_length) + x0*(BitsPerPixel/8);
00164         for (int i=0; i<xs; i++)
00165         {
00166           WORD* Pixel16 = (WORD*) DIB; // the current 16 bits pixel
00167           *db     = (BYTE) RGB16R(*Pixel16);
00168           *(db+1) = (BYTE) RGB16G(*Pixel16);
00169           *(db+2) = (BYTE) RGB16B(*Pixel16);
00170           db+=3;
00171           DIB+=2;
00172         }
00173       }
00174       break;
00175     default:
00176       vcl_cerr << "vidl_vil1_avicodec : Don't know how to process a "
00177                << BitsPerPixel << " bits per pixel AVI File.\n";
00178   } // end switch Bits per pixel
00179 
00180   return true;
00181 }
00182 
00183 
00184 //: put_section not implemented yet
00185 // we may need to change make_dib to
00186 // be able to put a section different
00187 // of the entire frame.
00188 int vidl_vil1_avicodec::put_section(int /*position*/,
00189                                     void* /*ib*/,
00190                                     int /*x0*/, int /*y0*/,
00191                                     int /*xs*/, int /*ys*/)
00192 {
00193   vcl_cerr << "vidl_vil1_avicodec::put_section not implemented\n";
00194   return -1;
00195 }
00196 
00197 //-----------------------------------------------------------------------------
00198 //: Probe the file fname, open it as an AVI file. If it works, return true, false otherwise.
00199 
00200 bool vidl_vil1_avicodec::probe(vcl_string const& fname)
00201 {
00202   int modenum = OF_READ | OF_SHARE_DENY_WRITE;
00203   AVIFileInit();
00204   if (AVIFileOpen(&avi_file_, fname.c_str(), modenum, 0L)==0)
00205   {
00206     // The file was opened with success
00207     // So, release it
00208     AVIFileRelease(avi_file_);
00209     // and return sucess
00210     return true;
00211   }
00212 
00213   return false;
00214 }
00215 
00216 vidl_vil1_codec_sptr vidl_vil1_avicodec::load(vcl_string const& fname, char mode)
00217 {
00218   int modenum = OF_READ;
00219   DWORD videostreamcode = 0x73646976; // corresponds to char string "vids"
00220 
00221   switch (mode) {
00222    case 'r':
00223     modenum = OF_READ | OF_SHARE_DENY_WRITE;
00224     break;
00225    case 'w':
00226     modenum = OF_READWRITE;
00227     break;
00228   }
00229 
00230   AVIFileInit();
00231   AVIFileOpen(&avi_file_, fname.c_str(), modenum, 0L);
00232 
00233   // only support first video stream
00234   if (AVIFileGetStream(avi_file_, &avi_stream_, videostreamcode, 0) != AVIERR_OK) {
00235     vcl_cerr << "[vidl_vil1_avicodec: no stream 0]";
00236   }
00237 
00238   if (!avi_file_ || !avi_stream_)
00239   {
00240     return NULL;
00241   }
00242 
00243   avi_get_frame_ = AVIStreamGetFrameOpen(avi_stream_, NULL);
00244 
00245   if (!read_header()) {
00246     vcl_fprintf(stderr, "vidl_vil1_avicodec: error reading header\n");
00247     return NULL;
00248   }
00249 
00250   set_format('L');
00251   set_image_class('C');
00252   set_name(vul_file::basename(fname));
00253   set_description(fname);
00254 
00255   // Open the first frame
00256   byte* DIB = (byte*) AVIStreamGetFrame(avi_get_frame_, 0);
00257 
00258   if ( ! DIB )
00259       return NULL;
00260 
00261   // Get the number of bits per pixel
00262   // and check the validity of width and height
00263   WORD BitsPerPixel = ((LPBITMAPINFOHEADER)DIB)->biBitCount;
00264   LONG iwidth = ((LPBITMAPINFOHEADER)DIB)->biWidth;
00265   LONG iheight = ((LPBITMAPINFOHEADER)DIB)->biHeight;
00266 
00267   if (width() != iwidth)
00268   {
00269     vcl_cerr << "vidl_vil1_avicodec::load ohoh, width of the first frame is different from the one specified for the avifile\n"
00270              << "          Movie width set with the first frame\n";
00271     set_width(iwidth);
00272   }
00273 
00274   if (height() != iheight)
00275   {
00276     vcl_cerr << "vidl_vil1_avicodec::load ohoh, height of the first frame is different from the one specified for the avifile\n"
00277              << "          Movie height set with the first frame\n";
00278     set_height(iheight);
00279   }
00280 
00281   // The movie will have 24 bits per pixel no matter of what
00282   // We can read 16 bits per pixel avi, but this will be
00283   // store in 24 bits per pixel frames
00284   set_bits_pixel(24); // set_bits_pixel(BitsPerPixel);
00285 
00286   //For the moment, we'll process 8 bits later
00287   if ((BitsPerPixel!=16) && (BitsPerPixel!=24))
00288   {
00289     vcl_cerr << "vidl_vil1_avicodec : Don't know how to process a "
00290              << BitsPerPixel << " bits per pixel AVI File.\n";
00291     return NULL;
00292   }
00293 
00294   return this;
00295 }
00296 
00297 
00298 bool vidl_vil1_avicodec::save(vidl_vil1_movie* movie, vcl_string const& fname)
00299 {
00300   PAVIFILE avi_file;
00301   AVISTREAMINFO avi_stream_info;
00302   PAVISTREAM avi_stream = NULL;
00303 
00304   HRESULT hr;
00305 
00306   AVIFileInit();
00307 
00308   //
00309   // Open the movie file for writing....
00310   //
00311   hr = AVIFileOpen(&avi_file,               // returned file pointer
00312                    fname.c_str(),           // file name
00313                    OF_WRITE | OF_CREATE,    // mode to open file with
00314                    NULL);                   // use handler determined
00315   // from file extension....
00316   if (hr != AVIERR_OK) {
00317     vcl_cerr << "vidl_vil1_avicodec : Could not open the file " << fname << " for writing.\n";
00318     if (hr == AVIERR_BADFORMAT)
00319       vcl_cerr << "vidl_vil1_avicodec : The file couldn't be read, indicating a corrupt file or an unrecognized format.\n";
00320     if (hr== AVIERR_MEMORY)
00321       vcl_cerr << "vidl_vil1_avicodec : The file could not be opened because of insufficient memory.\n";
00322     if (hr== AVIERR_FILEREAD)
00323       vcl_cerr << "vidl_vil1_avicodec : A disk error occurred while reading the file.\n";
00324     if (hr== AVIERR_FILEOPEN)
00325       vcl_cerr << "vidl_vil1_avicodec : A disk error occurred while opening the file.\n";
00326     if (hr== REGDB_E_CLASSNOTREG)
00327     {
00328       vcl_cerr << "vidl_vil1_avicodec : According to the registry, the type of file"
00329                << " specified in AVIFileOpen does not have a handler to process it.\n"
00330                << "vidl_vil1_avicodec : This is usually the case when the file name given does not have the .avi extension\n";
00331     }
00332     return false;
00333   }
00334 
00335   // Fill in the header for the video stream....
00336   //
00337   // The video stream will run in 30ths of a second....
00338 
00339   _fmemset(&avi_stream_info, 0, sizeof(avi_stream_info));
00340   avi_stream_info.fccType                = streamtypeVIDEO;// stream type
00341   avi_stream_info.fccHandler             = 0;
00342   avi_stream_info.dwScale                = 1;
00343   avi_stream_info.dwRate                 = movie->frame_rate();
00344   avi_stream_info.dwLength               = movie->length();
00345   avi_stream_info.dwSuggestedBufferSize  = movie->width()*movie->height()*3;//codec->get_bytes_pixel();
00346   SetRect(&avi_stream_info.rcFrame, 0, 0,             // rectangle for stream
00347           (int) movie->width(),
00348           (int) movie->height());
00349 
00350   // And create the stream;
00351   hr = AVIFileCreateStream(avi_file,                // file pointer
00352                            &avi_stream,             // returned stream pointer
00353                            &avi_stream_info);       // stream header
00354   if (hr != AVIERR_OK) {
00355     vcl_cerr << "vidl_vil1_avicodec : Could not create the avi stream.\n";
00356     return false;
00357   }
00358 
00359   if (encoder_type==ASKUSER)
00360   {
00361     // Compression mode
00362     AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
00363 
00364     if (!AVISaveOptions(NULL, 0, 1, &avi_stream, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
00365     {
00366       vcl_cerr << "vidl_vil1_avicodec : AVI Saving Cancelled.\n";
00367       return false;
00368     }
00369 
00370     encoder_options_valid=true;
00371   }
00372 
00373   char *fcc=(char *)&(opts.fccHandler);
00374 
00375   vcl_cout << "Compressor options:\n"
00376            << "fccHandler       = " << fcc[0] << "','" << fcc[1] << "','" << fcc[2] << "','" << fcc[3] << "'\n"
00377            << "key frame every  = " << opts.dwKeyFrameEvery << vcl_endl
00378            << "quality          = " << opts.dwQuality << vcl_endl
00379            << "flags            = " << opts.dwFlags  << vcl_endl;
00380   if (opts.dwFlags & AVICOMPRESSF_DATARATE)
00381     vcl_cout << "                   AVICOMPRESSF_DATARATE\n";
00382   if (opts.dwFlags & AVICOMPRESSF_INTERLEAVE)
00383     vcl_cout << "                   AVICOMPRESSF_INTERLEAVE\n";
00384   if (opts.dwFlags & AVICOMPRESSF_KEYFRAMES)
00385     vcl_cout << "                   AVICOMPRESSF_KEYFRAMES\n";
00386   if (opts.dwFlags & AVICOMPRESSF_VALID)
00387     vcl_cout << "                   AVICOMPRESSF_VALID\n";
00388   vcl_cout << "lpFormat         = " << opts.lpFormat << vcl_endl
00389            << "cbFormat         = " << opts.cbFormat << vcl_endl
00390            << "lpParms          = " << opts.lpParms << vcl_endl
00391            << "cbParms          = " << opts.cbParms << vcl_endl
00392            << "dwInterleaveEvery= " << opts.dwInterleaveEvery << vcl_endl;
00393 
00394   PAVISTREAM avi_stream_compressed = NULL;
00395   hr = AVIMakeCompressedStream(&avi_stream_compressed, avi_stream, &opts, NULL);
00396   if (hr != AVIERR_OK)
00397     return false;
00398 
00399   // Set the stream format
00400   {
00401     LPBITMAPINFOHEADER lpbi =
00402       (LPBITMAPINFOHEADER)GlobalLock(make_dib(movie->get_frame(0), 24));
00403     if (!lpbi)
00404     {
00405       vcl_cerr << "vidl_vil1_avicodec : DIB (Device Independent Bitmap) creation failed.\n";
00406       return false;
00407     }
00408     hr = AVIStreamSetFormat(avi_stream_compressed, 0,
00409                             lpbi,           // stream format
00410                             lpbi->biSize +   // format size
00411                             lpbi->biClrUsed * sizeof(RGBQUAD));
00412     if (hr != AVIERR_OK)
00413     {
00414       vcl_cerr << "vidl_vil1_avicodec : Could not set the AVI stream format.\n"
00415                << "                The chosen compression mode may not be installed well.\n";
00416       return false;
00417     }
00418   }
00419 
00420   // Write every frame
00421   int i = 0;
00422   for (vidl_vil1_movie::frame_iterator pframe = movie->begin();
00423        pframe <= movie->last();
00424        ++pframe, ++i)
00425     {
00426       LPBITMAPINFOHEADER lpbi =
00427         (LPBITMAPINFOHEADER)GlobalLock(make_dib(pframe, 24));
00428       if (!lpbi)
00429       {
00430         vcl_cerr << "vidl_vil1_avicodec : DIB (Device Independent Bitmap) creation failed.\n"
00431                  << "vidl_vil1_avicodec : Frame number " << i << vcl_endl;
00432         return false;
00433       }
00434 
00435       int time = i; // codec->GetT ...
00436       hr = AVIStreamWrite(avi_stream_compressed,
00437                           time,
00438                           1, // Number of samples to write
00439                           (LPBYTE) lpbi +               // pointer to data
00440                           lpbi->biSize +
00441                           lpbi->biClrUsed * sizeof(RGBQUAD),
00442                           lpbi->biSizeImage,
00443                           AVIIF_KEYFRAME,                        // flags....
00444                           NULL,
00445                           NULL);
00446       if (hr != AVIERR_OK)
00447       {
00448         vcl_cerr << "vidl_vil1_avicodec : Could not write to the AVI stream.\n";
00449         return false;
00450       }
00451     }
00452 
00453   if (avi_stream)
00454     AVIStreamRelease(avi_stream);
00455   if (avi_stream_compressed)
00456     AVIStreamRelease(avi_stream_compressed);
00457   if (avi_file)
00458     AVIFileRelease(avi_file);
00459   AVIFileExit();
00460 
00461   // Everything was OK
00462   return true;
00463 }
00464 
00465 #if 0
00466 //: Converts a microsoft four cc code to a 32 bit unsigned int.
00467 unsigned int vidl_vil1_avicodec::fccHandlerCoder(char c0, char c1, char c2, char c3)
00468 {
00469   unsigned int code;
00470 
00471   char *codeStr=(char *)(&code);
00472   codeStr[0]=c0;
00473   codeStr[1]=c1;
00474   codeStr[2]=c2;
00475   codeStr[3]=c3;
00476 
00477   return code
00478 }
00479 #endif // 0
00480 
00481 //: This function sets the encoder that is internally used to create the
00482 //  AVI. Using this function avoids the windows dialog asking
00483 //  the user for the compressor.
00484 //  Depending on the choosen encoder, the parameters of opts are set by this
00485 //  function.
00486 //
00487 //  @param encoder
00488 //     if encoder==ASKUSER      a windows dialog is used to choose the encoder
00489 //     if encoder==USEPREVIOUS  the options previously obtained from a call
00490 //                              to choose_encoder() with or without ASKUSER is used.
00491 //                              If not valid options have been obtained, UNCOMPRESSED is used.
00492 //     if encoder==UNCOMPRESSED Video is saved uncompressed.
00493 void vidl_vil1_avicodec::choose_encoder(AVIEncoderType encoder)
00494 {
00495   encoder_type=encoder;
00496 
00497   if (encoder_type==ASKUSER ||
00498       (encoder_type==USEPREVIOUS && encoder_options_valid))
00499     return;
00500 
00501   encoder_options_valid=true;
00502 
00503   switch (encoder_type)
00504   {
00505    case USEPREVIOUS:
00506    case UNCOMPRESSED:
00507     opts.fccType=streamtypeVIDEO;
00508     opts.fccHandler=mmioFOURCC('D','I','B',' ');
00509     opts.dwKeyFrameEvery=0;
00510     opts.dwQuality=0;
00511     opts.dwFlags=AVICOMPRESSF_VALID;
00512     opts.lpFormat=0;
00513     opts.cbFormat=0;
00514     opts.lpParms=0;
00515     opts.cbParms=0;
00516     opts.dwInterleaveEvery=0;
00517     break;
00518    case CINEPACK:
00519     opts.fccType=streamtypeVIDEO;
00520     opts.fccHandler=mmioFOURCC('c','v','i','d');
00521     opts.dwKeyFrameEvery=0;
00522     opts.dwQuality=10000;
00523     opts.dwFlags=AVICOMPRESSF_VALID;
00524     opts.lpFormat=0;
00525     opts.cbFormat=0;
00526     //The pointer to lpParms should actually point to four bytes of
00527     //memory containing the data 0x726c6f63, however, it seems to
00528     //work with all zeros also.
00529     //opts.lpParms = (LPVOID *)GlobalAlloc(NULL, 4);
00530     //opts.cbParms = 4;
00531     // *((long*)opts.lpParms) = 0x726c6f63;
00532     opts.lpParms=0;
00533     opts.cbParms=0;
00534     opts.dwInterleaveEvery=0;
00535     break;
00536    default:
00537     encoder_options_valid=false;
00538   }
00539 }
00540 
00541 //: Create a DIB (Device Independent Bitmap) from a frame.
00542 // (Note : make_dib is not guaranteed to work with bits!=24 for the moment)
00543 HANDLE  vidl_vil1_avicodec::make_dib(vidl_vil1_frame_sptr frame, UINT bits)
00544 {
00545   // 1st, Get the datas from the video frame
00546 
00547   byte* TjSection = new byte[frame->width() * frame->height() * frame->get_bytes_pixel()];
00548   if (!frame->get_section(TjSection, 0, 0, frame->width(), frame->height()) )
00549     vcl_cerr << "vidl_vil1_avicodec::make_dib--Could not read get section\n";
00550 
00551   // 2nd, Copy the array of bytes (and transform it),
00552   // so it is usable by a 'windows' BitMap
00553   //
00554 
00555   // The lenght of a row must be a multiple of 4 bytes
00556   // for windows bitmaps, so we will format them this way
00557   int line_length = (frame->width()*bits+31)/32 * 4;
00558 
00559   int data_size = line_length*frame->height()*(bits/8);
00560   // Create an array of bytes to receive the transformed datas
00561   byte* newbits = new byte[data_size];
00562   byte* db = (byte*) newbits;
00563   int i,j;
00564   for (i=0; i<data_size; i++)
00565   {
00566     *db = 0;
00567     ++db;
00568   }
00569 
00570   // Store the TargetJr data in a Bitmap way, DIB is a flipped upside down
00571   switch (frame->get_bytes_pixel())
00572   {
00573    case 3:
00574     for (j=frame->height()-1; j>=0;j--)
00575     {
00576       db = TjSection+ (j*frame->width())*frame->get_bytes_pixel();
00577       byte* DIB = newbits + (frame->height()-j-1)*line_length;
00578       for (i=0; i<frame->width(); ++i, DIB+=3, db+=3) {
00579         *DIB = *(db+2);
00580         *(DIB+1) = *(db+1);
00581         *(DIB+2) = *(db);
00582       }
00583     }
00584     break;
00585    case 1:
00586     for (j=frame->height()-1; j>=0;j--)
00587     {
00588       db = TjSection+ (j*frame->width())*frame->get_bytes_pixel();
00589       byte* DIB = newbits + (frame->height()-j-1)*line_length;
00590       for (i=0; i<frame->width(); ++i, DIB+=3, db+=1) {
00591         *DIB = *(db);
00592         *(DIB+1) = *(db);
00593         *(DIB+2) = *(db);
00594       }
00595     }
00596     break;
00597    default:
00598     vcl_cerr << "vidl_vil1_avicodec : Don't know how to deal with "
00599              << frame->get_bytes_pixel() << " bytes per pixel.\n";
00600 
00601   } // end switch byte per pixel
00602 
00603   // Get rid of the original datas
00604   delete[] TjSection;
00605 
00606   // 3st, Create the Bitmap and stick the datas in it
00607   HDC hdc = GetDC(NULL);
00608   HBITMAP hbitmap;
00609   if (!(hbitmap = CreateCompatibleBitmap(hdc,frame->width(),frame->height())))
00610   {
00611     vcl_cerr << "vidl_vil1_avicodec : Could not create a compatible bitmap for frame.\n";
00612     return NULL;
00613   }
00614   BITMAP bitmap;
00615   GetObject(hbitmap,sizeof(BITMAP),&bitmap);
00616   int wColSize = sizeof(RGBQUAD)*((bits <= 8) ? 1<<bits : 0);
00617   int dwSize = sizeof(BITMAPINFOHEADER) + wColSize +
00618     (DWORD)(UINT)line_length*(DWORD)(UINT)bitmap.bmHeight;
00619 
00620   //
00621   // Allocate room for a DIB and set the LPBI fields
00622   //
00623   HANDLE hdib = GlobalAlloc(GHND,dwSize);
00624   if (!hdib)
00625     return hdib;
00626 
00627   LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
00628 
00629   lpbi->biSize = sizeof(BITMAPINFOHEADER);
00630   lpbi->biWidth = bitmap.bmWidth;
00631   lpbi->biHeight = bitmap.bmHeight;
00632   lpbi->biPlanes = 1;
00633   lpbi->biBitCount = (WORD) bits;
00634   lpbi->biCompression = BI_RGB;
00635   lpbi->biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize;
00636   lpbi->biXPelsPerMeter = 0;
00637   lpbi->biYPelsPerMeter = 0;
00638   lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
00639   lpbi->biClrImportant = 0;
00640 
00641   hdc = CreateCompatibleDC(NULL); // Create Device Context
00642 
00643    // Put the bits in the bitmap
00644   int error_code = SetDIBits(hdc,hbitmap,0,bitmap.bmHeight,newbits,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
00645   if (!error_code)
00646   {
00647     vcl_cerr << "vidl_vil1_avicodec : Could set the bits in the BitMap.\n";
00648     return NULL;
00649   }
00650 
00651   //
00652   // Get the bits from the bitmap and stuff them after the LPBI
00653   //
00654   LPBYTE lpBits = (LPBYTE)(lpbi+1)+wColSize;
00655 
00656   // 4th, Stick the bits in the DIB
00657   error_code = GetDIBits(hdc,hbitmap,0,bitmap.bmHeight,lpBits,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
00658   if (!error_code)
00659   {
00660     vcl_cerr << "vidl_vil1_avicodec : Could set the bits in the DIB (Device Independent Bitmap).\n";
00661     return NULL;
00662   }
00663 
00664   // Fix this if GetDIBits messed it up....
00665   lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
00666 
00667   // Delete ressources
00668   DeleteBitmap(hbitmap);
00669   delete [] newbits;
00670   ReleaseDC(NULL,hdc);
00671   GlobalUnlock(hdib);
00672 
00673   return hdib;
00674 }

Generated on Tue Dec 2 05:09:13 2008 for core/vidl_vil1 by  doxygen 1.5.1