• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kstars

v4ldriver.cpp

Go to the documentation of this file.
00001 #if 0
00002     V4L INDI Driver
00003     INDI Interface for V4L devices
00004     Copyright (C) 2003-2005 Jasem Mutlaq (mutlaqja@ikarustech.com)
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Lesser General Public
00008     License as published by the Free Software Foundation; either
00009     version 2.1 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Lesser General Public License for more details.
00015 
00016     You should have received a copy of the GNU Lesser General Public
00017     License along with this library; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019 
00020 #endif
00021 
00022 #include "v4ldriver.h"
00023 
00024 V4L_Driver::V4L_Driver()
00025 {
00026   V4LFrame = (img_t *) malloc (sizeof(img_t));
00027  
00028   if (V4LFrame == NULL)
00029   {
00030      IDMessage(NULL, "Error: unable to initialize driver. Low memory.");
00031      IDLog("Error: unable to initialize driver. Low memory.");
00032      return;
00033   }
00034  
00035   camNameT[0].text  = NULL; 
00036   PortT[0].text     = NULL;
00037   IUSaveText(&PortT[0], "/dev/video0");
00038 
00039   divider = 128.;
00040  
00041 
00042 }
00043 
00044 V4L_Driver::~V4L_Driver()
00045 {
00046   free (V4LFrame);
00047 }
00048 
00049 
00050 void V4L_Driver::initProperties(const char *dev)
00051 {
00052   
00053   strncpy(device_name, dev, MAXINDIDEVICE);
00054  
00055   /* Connection */
00056   fillSwitch(&PowerS[0], "CONNECT", "Connect", ISS_OFF);
00057   fillSwitch(&PowerS[1], "DISCONNECT", "Disconnect", ISS_ON);
00058   fillSwitchVector(&PowerSP, PowerS, NARRAY(PowerS), dev, "CONNECTION", "Connection", COMM_GROUP, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
00059 
00060  /* Port */
00061   fillText(&PortT[0], "PORT", "Port", "/dev/ttyS0");
00062   fillTextVector(&PortTP, PortT, NARRAY(PortT), dev, "DEVICE_PORT", "Ports", COMM_GROUP, IP_RW, 0, IPS_IDLE);
00063 
00064  /* Video Stream */
00065   fillSwitch(&StreamS[0], "ON", "", ISS_OFF);
00066   fillSwitch(&StreamS[1], "OFF", "", ISS_ON);
00067   fillSwitchVector(&StreamSP, StreamS, NARRAY(StreamS), dev, "VIDEO_STREAM", "Video Stream", COMM_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
00068 
00069   /* Compression */
00070   fillSwitch(&CompressS[0], "ON", "", ISS_ON);
00071   fillSwitch(&CompressS[1], "OFF", "", ISS_OFF);
00072   fillSwitchVector(&CompressSP, CompressS, NARRAY(StreamS), dev, "Compression", "", IMAGE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
00073 
00074   /* Image type */
00075   fillSwitch(&ImageTypeS[0], "Grey", "", ISS_ON);
00076   fillSwitch(&ImageTypeS[1], "Color", "", ISS_OFF);
00077   fillSwitchVector(&ImageTypeSP, ImageTypeS, NARRAY(ImageTypeS), dev, "Image Type", "", IMAGE_GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
00078 
00079   /* Camera Name */
00080   fillText(&camNameT[0], "Model", "", "");
00081   fillTextVector(&camNameTP, camNameT, NARRAY(camNameT), dev, "Camera Model", "", COMM_GROUP, IP_RO, 0, IPS_IDLE);
00082   
00083   /* Expose */
00084   fillNumber(&ExposeTimeN[0], "EXPOSE_DURATION", "Duration (s)", "%5.2f", 0., 36000., 0.5, 1.);
00085   fillNumberVector(&ExposeTimeNP, ExposeTimeN, NARRAY(ExposeTimeN), dev, "CCD_EXPOSE_DURATION", "Expose", COMM_GROUP, IP_RW, 60, IPS_IDLE);
00086 
00087 /* Frame Rate */
00088   fillNumber(&FrameRateN[0], "RATE", "Rate", "%0.f", 1., 50., 1., 10.);
00089   fillNumberVector(&FrameRateNP, FrameRateN, NARRAY(FrameRateN), dev, "FRAME_RATE", "Frame Rate", COMM_GROUP, IP_RW, 60, IPS_IDLE);
00090 
00091   /* Frame dimension */
00092   fillNumber(&FrameN[0], "X", "X", "%.0f", 0., 0., 0., 0.);
00093   fillNumber(&FrameN[1], "Y", "Y", "%.0f", 0., 0., 0., 0.);
00094   fillNumber(&FrameN[2], "WIDTH", "Width", "%.0f", 0., 0., 10., 0.);
00095   fillNumber(&FrameN[3], "HEIGHT", "Height", "%.0f", 0., 0., 10., 0.);
00096   fillNumberVector(&FrameNP, FrameN, NARRAY(FrameN), dev, "CCD_FRAME", "Frame", IMAGE_GROUP, IP_RW, 60, IPS_IDLE);
00097 
00098   /*fillNumber(&ImageSizeN[0], "WIDTH", "Width", "%0.f", 0., 0., 10., 0.);
00099   fillNumber(&ImageSizeN[1], "HEIGHT", "Height", "%0.f", 0., 0., 10., 0.);
00100   fillNumberVector(&ImageSizeNP, ImageSizeN, NARRAY(ImageSizeN), dev, "IMAGE_SIZE", "Image Size", IMAGE_GROUP, IP_RW, 60, IPS_IDLE);*/
00101   
00102   #ifndef HAVE_LINUX_VIDEODEV2_H
00103   fillNumber(&ImageAdjustN[0], "Contrast", "", "%0.f", 0., 256., 1., 0.);
00104   fillNumber(&ImageAdjustN[1], "Brightness", "", "%0.f", 0., 256., 1., 0.);
00105   fillNumber(&ImageAdjustN[2], "Hue", "", "%0.f", 0., 256., 1., 0.);
00106   fillNumber(&ImageAdjustN[3], "Color", "", "%0.f", 0., 256., 1., 0.);
00107   fillNumber(&ImageAdjustN[4], "Whiteness", "", "%0.f", 0., 256., 1., 0.);
00108   fillNumberVector(&ImageAdjustNP, ImageAdjustN, NARRAY(ImageAdjustN), dev, "Image Adjustments", "", IMAGE_GROUP, IP_RW, 60, IPS_IDLE);
00109   #else
00110   fillNumberVector(&ImageAdjustNP, NULL, 0, dev, "Image Adjustments", "", IMAGE_GROUP, IP_RW, 60, IPS_IDLE);
00111   #endif 
00112 
00113   // We need to setup the BLOB (Binary Large Object) below. Using this property, we can send FITS to our client
00114   strcpy(imageB.name, "CCD1");
00115   strcpy(imageB.label, "Feed");
00116   strcpy(imageB.format, "");
00117   imageB.blob    = 0;
00118   imageB.bloblen = 0;
00119   imageB.size    = 0;
00120   imageB.bvp     = 0;
00121   imageB.aux0    = 0;
00122   imageB.aux1    = 0;
00123   imageB.aux2    = 0;
00124   
00125   strcpy(imageBP.device, dev);
00126   strcpy(imageBP.name, "Video");
00127   strcpy(imageBP.label, "Video");
00128   strcpy(imageBP.group, COMM_GROUP);
00129   strcpy(imageBP.timestamp, "");
00130   imageBP.p       = IP_RO;
00131   imageBP.timeout = 0;
00132   imageBP.s       = IPS_IDLE;
00133   imageBP.bp      = &imageB;
00134   imageBP.nbp     = 1;
00135   imageBP.aux     = 0;
00136 
00137 }
00138 
00139 void V4L_Driver::initCamBase()
00140 {
00141    #ifndef HAVE_LINUX_VIDEODEV2_H
00142     v4l_base = new V4L1_Base();
00143    #else
00144     v4l_base = new V4L2_Base();
00145    #endif
00146 }
00147 
00148 void V4L_Driver::ISGetProperties (const char *dev)
00149 { 
00150 
00151   if (dev && strcmp (device_name, dev))
00152     return;
00153 
00154   /* COMM_GROUP */
00155   IDDefSwitch(&PowerSP, NULL);
00156   IDDefText(&PortTP, NULL);
00157   IDDefText(&camNameTP, NULL);
00158   IDDefSwitch(&StreamSP, NULL);
00159   #ifndef HAVE_LINUX_VIDEODEV2_H
00160   IDDefNumber(&FrameRateNP, NULL);
00161   #endif
00162   IDDefNumber(&ExposeTimeNP, NULL);
00163   IDDefBLOB(&imageBP, NULL);
00164   
00165   /* Image properties */
00166   IDDefSwitch(&CompressSP, NULL);
00167   IDDefSwitch(&ImageTypeSP, NULL);
00168   IDDefNumber(&FrameNP, NULL);
00169   
00170   #ifndef HAVE_LINUX_VIDEODEV2_H
00171   IDDefNumber(&ImageAdjustNP, NULL);
00172   #endif
00173 
00174 
00175   
00176 }
00177  
00178 void V4L_Driver::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
00179 {
00180     char errmsg[ERRMSGSIZ];
00181 
00182     /* ignore if not ours */
00183     if (dev && strcmp (device_name, dev))
00184         return;
00185         
00186      /* Connection */
00187      if (!strcmp (name, PowerSP.name))
00188      {
00189           IUResetSwitches(&PowerSP);
00190       IUUpdateSwitches(&PowerSP, states, names, n);
00191       connectCamera();
00192       return;
00193      }
00194 
00195      /* Compression */
00196      if (!strcmp(name, CompressSP.name))
00197      {
00198        IUResetSwitches(&CompressSP);
00199        IUUpdateSwitches(&CompressSP, states, names, n);
00200        CompressSP.s = IPS_OK;
00201        
00202        IDSetSwitch(&CompressSP, NULL);
00203        return;
00204      }    
00205 
00206      /* Image Type */
00207      if (!strcmp(name, ImageTypeSP.name))
00208      {
00209        IUResetSwitches(&ImageTypeSP);
00210        IUUpdateSwitches(&ImageTypeSP, states, names, n);
00211        ImageTypeSP.s = IPS_OK;
00212        
00213        IDSetSwitch(&ImageTypeSP, NULL);
00214        return;
00215      }
00216      
00217      /* Video Stream */
00218      if (!strcmp(name, StreamSP.name))
00219      {
00220      
00221       if (checkPowerS(&StreamSP))
00222          return;
00223        
00224        IUResetSwitches(&StreamSP);
00225        IUUpdateSwitches(&StreamSP, states, names, n);
00226        StreamSP.s = IPS_IDLE;
00227        
00228           
00229        if (StreamS[0].s == ISS_ON)
00230        {
00231          frameCount = 0;
00232          IDLog("Starting the video stream.\n");
00233          v4l_base->start_capturing(errmsg);
00234      StreamSP.s  = IPS_BUSY; 
00235        }
00236        else
00237        {
00238          IDLog("The video stream has been disabled. Frame count %d\n", frameCount);
00239          v4l_base->stop_capturing(errmsg);
00240        }
00241        
00242        IDSetSwitch(&StreamSP, NULL);
00243        return;
00244      }
00245      
00246 }
00247 
00248 void V4L_Driver::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int /*n*/)
00249 {
00250     IText *tp;
00251 
00252 
00253        /* ignore if not ours */ 
00254        if (dev && strcmp (device_name, dev))
00255          return;
00256 
00257     if (!strcmp(name, PortTP.name) )
00258     {
00259       PortTP.s = IPS_OK;
00260       tp = IUFindText( &PortTP, names[0] );
00261       if (!tp)
00262        return;
00263 
00264           IUSaveText(tp, texts[0]);
00265       IDSetText (&PortTP, NULL);
00266       return;
00267     }
00268 }
00269 
00270 void V4L_Driver::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
00271 {
00272       char errmsg[ERRMSGSIZ];
00273 
00274     /* ignore if not ours */
00275     if (dev && strcmp (device_name, dev))
00276         return;
00277         
00278     
00279     /* Frame Size */
00280     if (!strcmp (FrameNP.name, name))
00281     {
00282       if (checkPowerN(&FrameNP))
00283         return;
00284     
00285        int oldW = (int) FrameN[2].value;
00286        int oldH = (int) FrameN[3].value;
00287 
00288       FrameNP.s = IPS_OK;
00289       
00290       if (IUUpdateNumbers(&FrameNP, values, names, n) < 0)
00291        return;
00292       
00293       if (v4l_base->setSize( (int) FrameN[2].value, (int) FrameN[3].value) != -1)
00294       {
00295          FrameN[2].value = v4l_base->getWidth();
00296      FrameN[3].value = v4l_base->getHeight();
00297          IDSetNumber(&FrameNP, NULL);
00298      return;
00299       }
00300       else
00301       {
00302         FrameN[2].value = oldW;
00303     FrameN[3].value = oldH;
00304         FrameNP.s = IPS_ALERT;
00305     IDSetNumber(&FrameNP, "Failed to set a new image size.");
00306       }
00307       
00308       return;
00309    }
00310 
00311    #ifndef HAVE_LINUX_VIDEODEV2_H
00312    /* Frame rate */
00313    if (!strcmp (FrameRateNP.name, name))
00314    {
00315      if (checkPowerN(&FrameRateNP))
00316       return;
00317       
00318      FrameRateNP.s = IPS_IDLE;
00319      
00320      if (IUUpdateNumbers(&FrameRateNP, values, names, n) < 0)
00321        return;
00322        
00323      v4l_base->setFPS( (int) FrameRateN[0].value );
00324      
00325      FrameRateNP.s = IPS_OK;
00326      IDSetNumber(&FrameRateNP, NULL);
00327      return;
00328    }
00329    #endif
00330    
00331    
00332    if (!strcmp (ImageAdjustNP.name, name))
00333    {
00334      if (checkPowerN(&ImageAdjustNP))
00335        return;
00336        
00337      ImageAdjustNP.s = IPS_IDLE;
00338      
00339      if (IUUpdateNumbers(&ImageAdjustNP, values, names, n) < 0)
00340        return;
00341      
00342      #ifndef HAVE_LINUX_VIDEODEV2_H
00343      v4l_base->setContrast( (int) (ImageAdjustN[0].value * divider));
00344      v4l_base->setBrightness( (int) (ImageAdjustN[1].value * divider));
00345      v4l_base->setHue( (int) (ImageAdjustN[2].value * divider));
00346      v4l_base->setColor( (int) (ImageAdjustN[3].value * divider));
00347      v4l_base->setWhiteness( (int) (ImageAdjustN[4].value * divider));
00348      
00349      ImageAdjustN[0].value = v4l_base->getContrast() / divider;
00350      ImageAdjustN[1].value = v4l_base->getBrightness() / divider;
00351      ImageAdjustN[2].value = v4l_base->getHue() / divider;
00352      ImageAdjustN[3].value = v4l_base->getColor() / divider;
00353      ImageAdjustN[4].value = v4l_base->getWhiteness() / divider;
00354 
00355      #else
00356      unsigned int ctrl_id;
00357      for (int i=0; i < ImageAdjustNP.nnp; i++)
00358      {
00359          ctrl_id = *((unsigned int *) ImageAdjustNP.np[i].aux0);
00360          if (v4l_base->setINTControl( ctrl_id , ImageAdjustNP.np[i].value, errmsg) < 0)
00361          {
00362             ImageAdjustNP.s = IPS_ALERT;
00363             IDSetNumber(&ImageAdjustNP, "Unable to adjust setting. %s", errmsg);
00364             return;
00365          }
00366      }
00367      #endif
00368      
00369      ImageAdjustNP.s = IPS_OK;
00370      IDSetNumber(&ImageAdjustNP, NULL);
00371      return;
00372    }
00373    
00374    
00375     /* Exposure */
00376     if (!strcmp (ExposeTimeNP.name, name))
00377     {
00378        
00379        if (checkPowerN(&ExposeTimeNP))
00380          return;
00381     
00382         if (StreamS[0].s == ISS_ON) 
00383           v4l_base->stop_capturing(errmsg);
00384 
00385     StreamS[0].s  = ISS_OFF;
00386     StreamS[1].s  = ISS_ON;
00387     StreamSP.s    = IPS_IDLE;
00388     IDSetSwitch(&StreamSP, NULL);
00389         
00390     V4LFrame->expose = 1000;
00391 
00392         v4l_base->start_capturing(errmsg);
00393         ExposeTimeNP.s   = IPS_BUSY;
00394     IDSetNumber(&ExposeTimeNP, NULL);
00395     
00396         return;
00397     } 
00398       
00399   
00400     
00401 }
00402 
00403 void V4L_Driver::newFrame(void *p)
00404 {
00405   ((V4L_Driver *) (p))->updateFrame();
00406 }
00407 
00408 void V4L_Driver::updateFrame()
00409 {
00410   char errmsg[ERRMSGSIZ];
00411   static int dropLarge = 3;
00412 
00413   if (StreamSP.s == IPS_BUSY)
00414   {
00415       frameCount++;
00416 
00417      // Drop some frames
00418      if (FrameN[2].value > 160)
00419      {
00420         dropLarge--;
00421         if (dropLarge == 0)
00422         {
00423           dropLarge = 3;
00424           return;
00425         }
00426         else if (dropLarge < 2) return;
00427         
00428       }
00429 
00430      updateStream();
00431   }
00432   else if (ExposeTimeNP.s == IPS_BUSY)
00433   {
00434      V4LFrame->Y      = v4l_base->getY();
00435      v4l_base->stop_capturing(errmsg);
00436      grabImage();
00437   }
00438 
00439 }
00440 
00441 void V4L_Driver::updateStream()
00442 {
00443  
00444    int width  = v4l_base->getWidth();
00445    int height = v4l_base->getHeight();
00446    uLongf compressedBytes = 0;
00447    uLong totalBytes;
00448    unsigned char *targetFrame;
00449    int r;
00450    
00451    if (PowerS[0].s == ISS_OFF || StreamS[0].s == ISS_OFF) return;
00452    
00453    if (ImageTypeS[0].s == ISS_ON)
00454       V4LFrame->Y           = v4l_base->getY();
00455    else
00456       V4LFrame->colorBuffer     = v4l_base->getColorBuffer();
00457   
00458    totalBytes  = ImageTypeS[0].s == ISS_ON ? width * height : width * height * 4;
00459    targetFrame = ImageTypeS[0].s == ISS_ON ? V4LFrame->Y : V4LFrame->colorBuffer;
00460 
00461    /* Do we want to compress ? */
00462     if (CompressS[0].s == ISS_ON)
00463     {   
00464     /* Compress frame */
00465     V4LFrame->compressedFrame = (unsigned char *) realloc (V4LFrame->compressedFrame, sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3);
00466    
00467     compressedBytes = sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3;
00468    
00469     r = compress2(V4LFrame->compressedFrame, &compressedBytes, targetFrame, totalBytes, 4);
00470     if (r != Z_OK)
00471     {
00472         /* this should NEVER happen */
00473         IDLog("internal error - compression failed: %d\n", r);
00474         return;
00475     }
00476    
00477     /* #3.A Send it compressed */
00478     imageB.blob = V4LFrame->compressedFrame;
00479     imageB.bloblen = compressedBytes;
00480     imageB.size = totalBytes;
00481     strcpy(imageB.format, ".stream.z");
00482      }
00483      else
00484      {
00485        /* #3.B Send it uncompressed */
00486         imageB.blob = targetFrame;
00487     imageB.bloblen = totalBytes;
00488     imageB.size = totalBytes;
00489     strcpy(imageB.format, ".stream");
00490      }
00491         
00492    imageBP.s = IPS_OK;
00493    IDSetBLOB (&imageBP, NULL);
00494    
00495    #ifndef HAVE_LINUX_VIDEODEV2_H
00496       char errmsg[ERRMSGSIZ];
00497       v4l_base->start_capturing(errmsg);
00498    #endif
00499 }
00500 
00501 /* Downloads the image from the CCD row by row and store them
00502    in a raw file.
00503  N.B. No processing is done on the image */
00504 int V4L_Driver::grabImage()
00505 {
00506    int err, fd;
00507    char errmsg[ERRMSG_SIZE];
00508    char filename[] = "/tmp/fitsXXXXXX";
00509   
00510    
00511    if ((fd = mkstemp(filename)) < 0)
00512    { 
00513     IDMessage(device_name, "Error making temporary filename.");
00514     IDLog("Error making temporary filename.\n");
00515     return -1;
00516    }
00517    close(fd);
00518   
00519    err = writeFITS(filename, errmsg);
00520    if (err)
00521    {
00522        IDMessage(device_name, errmsg, NULL);
00523        return -1;
00524    }
00525    
00526   return 0;
00527 }
00528 
00529 int V4L_Driver::writeFITS(const char * filename, char errmsg[])
00530 {
00531   FITS_FILE* ofp;
00532   int i, bpp, bpsl, width, height;
00533   long nbytes;
00534   FITS_HDU_LIST *hdu;
00535   
00536   ofp = fits_open (filename, "w");
00537   if (!ofp)
00538   {
00539     snprintf(errmsg, ERRMSG_SIZE, "Error: cannot open file for writing.");
00540     return (-1);
00541   }
00542   
00543   width  = v4l_base->getWidth();
00544   height = v4l_base->getHeight();
00545   bpp    = 1;                      /* Bytes per Pixel */
00546   bpsl   = bpp * width;        /* Bytes per Line */
00547   nbytes = 0;
00548   
00549   hdu = create_fits_header (ofp, width, height, bpp);
00550   if (hdu == NULL)
00551   {
00552      snprintf(errmsg, ERRMSG_SIZE, "Error: creating FITS header failed.");
00553      return (-1);
00554   }
00555   if (fits_write_header (ofp, hdu) < 0)
00556   {
00557     snprintf(errmsg, ERRMSG_SIZE, "Error: writing to FITS header failed.");
00558     return (-1);
00559   }
00560   
00561   for (i= height - 1; i >=0 ; i--) 
00562   {
00563     fwrite(V4LFrame->Y + (i * width), 1, width, ofp->fp);
00564     nbytes += bpsl;
00565   }
00566   
00567   nbytes = nbytes % FITS_RECORD_SIZE;
00568   if (nbytes)
00569   {
00570     while (nbytes++ < FITS_RECORD_SIZE)
00571       putc (0, ofp->fp);
00572   }
00573   
00574   if (ferror (ofp->fp))
00575   {
00576     snprintf(errmsg, ERRMSG_SIZE, "Error: write error occured");
00577     return (-1);
00578   }
00579  
00580  fits_close (ofp);      
00581  
00582   /* Success */
00583  ExposeTimeNP.s = IPS_OK;
00584  IDSetNumber(&ExposeTimeNP, NULL);
00585  
00586  uploadFile(filename);
00587   
00588  return 0;
00589 
00590 }
00591 
00592 void V4L_Driver::uploadFile(const char * filename)
00593 {
00594    
00595    FILE * fitsFile;
00596    unsigned char *fitsData;
00597    int r=0;
00598    unsigned int nr = 0;
00599    uLong  totalBytes;
00600    uLongf compressedBytes = 0;
00601    struct stat stat_p; 
00602  
00603    if ( -1 ==  stat (filename, &stat_p))
00604    { 
00605      IDLog(" Error occoured attempting to stat %s\n", filename); 
00606      return; 
00607    }
00608    
00609    totalBytes = stat_p.st_size;
00610    fitsData = new unsigned char[totalBytes];
00611 
00612    fitsFile = fopen(filename, "r");
00613    
00614    if (fitsFile == NULL)
00615     return;
00616    
00617    /* #1 Read file from disk */ 
00618    for (unsigned int i=0; i < totalBytes; i+= nr)
00619    {
00620       nr = fread(fitsData + i, 1, totalBytes - i, fitsFile);
00621      
00622      if (nr <= 0)
00623      {
00624         IDLog("Error reading temporary FITS file.\n");
00625         return;
00626      }
00627    }
00628    
00629    if (CompressS[0].s == ISS_ON)
00630    {   
00631    /* #2 Compress it */
00632    V4LFrame->compressedFrame = (unsigned char *) realloc (V4LFrame->compressedFrame, sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3);
00633    
00634     compressedBytes = sizeof(unsigned char) * totalBytes + totalBytes / 64 + 16 + 3;
00635      
00636      
00637    r = compress2(V4LFrame->compressedFrame, &compressedBytes, fitsData, totalBytes, 9);
00638    if (r != Z_OK)
00639    {
00640     /* this should NEVER happen */
00641     IDLog("internal error - compression failed: %d\n", r);
00642     return;
00643    }
00644 
00645    /* #3.A Send it compressed */
00646    imageB.blob = V4LFrame->compressedFrame;
00647    imageB.bloblen = compressedBytes;
00648    imageB.size = totalBytes;
00649    strcpy(imageB.format, ".fits.z");
00650    }
00651    else
00652    {
00653      imageB.blob = fitsData;
00654      imageB.bloblen = totalBytes;
00655      imageB.size = totalBytes;
00656      strcpy(imageB.format, ".fits");
00657    }
00658    
00659    imageBP.s = IPS_OK;
00660    IDSetBLOB (&imageBP, NULL);
00661    
00662    delete (fitsData);
00663 } 
00664 
00665 void V4L_Driver::connectCamera()
00666 {
00667   char errmsg[ERRMSGSIZ];
00668   
00669     
00670   switch (PowerS[0].s)
00671   {
00672      case ISS_ON:
00673       if (v4l_base->connectCam(PortT[0].text, errmsg) < 0)
00674       {
00675       PowerSP.s = IPS_IDLE;
00676       PowerS[0].s = ISS_OFF;
00677       PowerS[1].s = ISS_ON;
00678       IDSetSwitch(&PowerSP, "Error: unable to open device");
00679       IDLog("Error: %s\n", errmsg);
00680       return;
00681       }
00682       
00683       /* Sucess! */
00684       PowerS[0].s = ISS_ON;
00685       PowerS[1].s = ISS_OFF;
00686       PowerSP.s = IPS_OK;
00687       IDSetSwitch(&PowerSP, "Video4Linux Generic Device is online. Retrieving basic data.");
00688 
00689       v4l_base->registerCallback(newFrame, this);
00690       
00691       V4LFrame->compressedFrame = (unsigned char *) malloc (sizeof(unsigned char) * 1);
00692       
00693       IDLog("V4L Device is online. Retrieving basic data.\n");
00694       getBasicData();
00695       
00696       break;
00697       
00698     case ISS_OFF:
00699       PowerS[0].s = ISS_OFF;
00700       PowerS[1].s = ISS_ON;
00701       PowerSP.s = IPS_IDLE;
00702       
00703       free(V4LFrame->compressedFrame);
00704       V4LFrame->compressedFrame = NULL;
00705       v4l_base->disconnectCam();
00706       
00707       IDSetSwitch(&PowerSP, "Video4Linux Generic Device is offline.");
00708       
00709       break;
00710      }
00711 }
00712 
00713 /* Retrieves basic data from the device upon connection.*/
00714 void V4L_Driver::getBasicData()
00715 {
00716 
00717   int xmax, ymax, xmin, ymin;
00718   
00719   v4l_base->getMaxMinSize(xmax, ymax, xmin, ymin);
00720   
00721   /* Width */
00722   FrameN[2].value = v4l_base->getWidth();
00723   FrameN[2].min = xmin;
00724   FrameN[2].max = xmax;
00725   
00726   /* Height */
00727   FrameN[3].value = v4l_base->getHeight();
00728   FrameN[3].min = ymin;
00729   FrameN[3].max = ymax;
00730   
00731   IUUpdateMinMax(&FrameNP);
00732   IDSetNumber(&FrameNP, NULL);
00733   
00734   IUSaveText(&camNameT[0], v4l_base->getDeviceName());
00735   IDSetText(&camNameTP, NULL);
00736 
00737    #ifndef HAVE_LINUX_VIDEODEV2_H
00738      updateV4L1Controls();
00739    #else
00740     updateV4L2Controls();
00741    #endif
00742    
00743 }
00744 
00745 #ifdef HAVE_LINUX_VIDEODEV2_H
00746 void V4L_Driver::updateV4L2Controls()
00747 {
00748     // #1 Query for INTEGER controls, and fill up the structure
00749       free(ImageAdjustNP.np);
00750       ImageAdjustNP.nnp = 0;
00751       
00752    if (v4l_base->queryINTControls(&ImageAdjustNP) > 0)
00753       IDDefNumber(&ImageAdjustNP, NULL);
00754 }
00755 #else
00756 void V4L_Driver::updateV4L1Controls()
00757 {
00758 
00759   if ( (v4l_base->getContrast() / divider) > ImageAdjustN[0].max)
00760       divider *=2;
00761 
00762   if ( (v4l_base->getHue() / divider) > ImageAdjustN[2].max)
00763       divider *=2;
00764 
00765   ImageAdjustN[0].value = v4l_base->getContrast() / divider;
00766   ImageAdjustN[1].value = v4l_base->getBrightness() / divider;
00767   ImageAdjustN[2].value = v4l_base->getHue() / divider;
00768   ImageAdjustN[3].value = v4l_base->getColor() / divider;
00769   ImageAdjustN[4].value = v4l_base->getWhiteness() / divider;
00770 
00771   ImageAdjustNP.s = IPS_OK;
00772   IDSetNumber(&ImageAdjustNP, NULL);
00773   
00774 }
00775 #endif
00776 
00777 int V4L_Driver::checkPowerS(ISwitchVectorProperty *sp)
00778 {
00779   if (PowerSP.s != IPS_OK)
00780   {
00781     if (!strcmp(sp->label, ""))
00782         IDMessage (device_name, "Cannot change property %s while the camera is offline.", sp->name);
00783     else
00784         IDMessage (device_name, "Cannot change property %s while the camera is offline.", sp->label);
00785     
00786     sp->s = IPS_IDLE;
00787     IDSetSwitch(sp, NULL);
00788     return -1;
00789   }
00790 
00791   return 0;
00792 }
00793 
00794 int V4L_Driver::checkPowerN(INumberVectorProperty *np)
00795 {
00796    
00797   if (PowerSP.s != IPS_OK)
00798   {
00799     if (!strcmp(np->label, ""))
00800         IDMessage (device_name, "Cannot change property %s while the camera is offline.", np->name);
00801     else
00802         IDMessage (device_name, "Cannot change property %s while the camera is offline.", np->label);
00803     
00804     np->s = IPS_IDLE;
00805     IDSetNumber(np, NULL);
00806     return -1;
00807   }
00808 
00809   return 0;
00810 }
00811 
00812 int V4L_Driver::checkPowerT(ITextVectorProperty *tp)
00813 {
00814 
00815   if (PowerSP.s != IPS_OK)
00816   {
00817     if (!strcmp(tp->label, ""))
00818         IDMessage (device_name, "Cannot change property %s while the camera is offline.", tp->name);
00819     else
00820         IDMessage (device_name, "Cannot change property %s while the camera is offline.", tp->label);
00821     
00822     tp->s = IPS_IDLE;
00823     IDSetText(tp, NULL);
00824     return -1;
00825   }
00826 
00827   return 0;
00828 
00829 }
00830 
00831 FITS_HDU_LIST * V4L_Driver::create_fits_header (FITS_FILE *ofp, uint width, uint height, uint bpp)
00832 {
00833 
00834  FITS_HDU_LIST *hdulist;
00835  char expose_s[80];
00836  char obsDate[80];
00837  char instrumentName[80];
00838  char ts[32];
00839     
00840  struct tm *tp;
00841  time_t t;
00842  time (&t);
00843  tp = gmtime (&t);
00844  strftime (ts, sizeof(ts), "%Y-%m-%dT%H:%M:%S", tp);
00845  
00846  snprintf(instrumentName, 80, "INSTRUME= '%s'", v4l_base->getDeviceName());
00847  snprintf(obsDate, 80, "DATE-OBS= '%s' /Observation Date UTC", ts);
00848 
00849  hdulist = fits_add_hdu (ofp);
00850  if (hdulist == NULL) return (NULL);
00851 
00852  hdulist->used.simple = 1;
00853  hdulist->bitpix = 8;
00854  hdulist->naxis = 2;
00855  hdulist->naxisn[0] = width;
00856  hdulist->naxisn[1] = height;
00857  hdulist->naxisn[2] = bpp;
00858  hdulist->used.datamin = 0;
00859  hdulist->used.datamax = 0;
00860  hdulist->used.bzero = 1;
00861  hdulist->bzero = 0.0;
00862  hdulist->used.bscale = 1;
00863  hdulist->bscale = 1.0;
00864  
00865  snprintf(expose_s, sizeof(expose_s), "EXPOSURE= %d / milliseconds", V4LFrame->expose);
00866  
00867  fits_add_card (hdulist, expose_s);
00868  fits_add_card (hdulist, instrumentName);
00869  fits_add_card (hdulist, obsDate);
00870  
00871  return (hdulist);
00872 }
00873 
00874 
00875 

kstars

Skip menu "kstars"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • keduca
  • kstars
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal