os/linux-2.6-tag--devboard-R2_10-4/arch/cris/arch-v32/drivers/elphel/jpeghead.c

Go to the documentation of this file.
00001 /*!***************************************************************************
00002 *! FILE NAME  : jpeghead.c
00003 *! DESCRIPTION: handleng JPEG file headers
00004 *!
00005 *! Copyright (C) 2008 Elphel, Inc
00006 *! -----------------------------------------------------------------------------**
00007 *!
00008 *!  This program is free software: you can redistribute it and/or modify
00009 *!  it under the terms of the GNU General Public License as published by
00010 *!  the Free Software Foundation, either version 3 of the License, or
00011 *!  (at your option) any later version.
00012 *!
00013 *!  This program is distributed in the hope that it will be useful,
00014 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 *!  GNU General Public License for more details.
00017 *!
00018 *!  You should have received a copy of the GNU General Public License
00019 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020 *! -----------------------------------------------------------------------------**
00021 *!  $Log: jpeghead.c,v $
00022 *!  Revision 1.1.1.1  2008/11/27 20:04:01  elphel
00023 *!
00024 *!
00025 *!  Revision 1.10  2008/11/03 18:43:18  elphel
00026 *!  8.0.alpha12 with working apps/astreamer
00027 *!
00028 *!  Revision 1.9  2008/10/29 04:18:28  elphel
00029 *!  v.8.0.alpha10 made a separate structure for global parameters (not related to particular frames in a frame queue)
00030 *!
00031 *!  Revision 1.8  2008/10/12 16:46:22  elphel
00032 *!  snapshot
00033 *!
00034 *!  Revision 1.7  2008/10/06 08:31:08  elphel
00035 *!  snapshot, first images
00036 *!
00037 *!  Revision 1.6  2008/09/22 22:55:48  elphel
00038 *!  snapshot
00039 *!
00040 *!  Revision 1.5  2008/09/19 04:37:25  elphel
00041 *!  snapshot
00042 *!
00043 *!  Revision 1.4  2008/09/12 20:40:12  elphel
00044 *!  snapshot
00045 *!
00046 *!  Revision 1.3  2008/09/12 00:23:59  elphel
00047 *!  removed cc353.c, cc353.h
00048 *!
00049 *!  Revision 1.2  2008/09/11 01:05:32  elphel
00050 *!  snapshot
00051 *!
00052 *!  Revision 1.1  2008/09/07 19:48:09  elphel
00053 *!  snapshot
00054 *!
00055 */
00056 
00057 /****************** INCLUDE FILES SECTION ***********************************/
00058 
00059 
00060 #include <linux/module.h>
00061 #include <linux/mm.h>
00062 #include <linux/sched.h>
00063 #include <linux/slab.h>
00064 #include <linux/errno.h>
00065 #include <linux/kernel.h>
00066 #include <linux/fs.h>
00067 #include <linux/string.h>
00068 #include <linux/init.h>
00069 #include <linux/autoconf.h>
00070 #include <linux/time.h>
00071 
00072 #include <asm/system.h>
00073 #include <asm/arch/memmap.h>
00074 //#include <asm/svinto.h> obsolete
00075 #include <asm/io.h>
00076 
00077 #include <asm/arch/dma.h>
00078 #include <asm/arch/hwregs/dma_defs.h>
00079 #include <asm/arch/hwregs/dma.h>
00080 #include <asm/arch/hwregs/reg_map.h>
00081 #include <asm/arch/hwregs/bif_dma_defs.h>
00082 
00083 
00084 #include <asm/irq.h>
00085 #include <asm/atomic.h>
00086 
00087 
00088 #include <asm/delay.h>
00089 #include <asm/uaccess.h>
00090 #include <asm/elphel/c313a.h>
00091 #include "fpga_io.h"//fpga_table_write_nice
00092 #include "jpeghead.h"
00093 #include "fpgactrl.h"  // defines port_csp0_addr, port_csp4_addr 
00094 #include "framepars.h" // extern pastpars
00095 #include "quantization_tables.h" // get_gtables()
00096 #include "x3x3.h"
00097 //#include "cc3x3.h"
00098 #include "cxdma.h"
00099 //#include "circbuf.h"
00100 #include "sensor_common.h"
00101 #include "exif.h"
00102 
00103 #if ELPHEL_DEBUG
00104  #define   MDF(x) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__ );x ;}
00105  #define   D17(x) { if (GLOBALPARS(G_DEBUG) & (1 <<17)) {x; } ; }
00106  #define MDF17(x) { if (GLOBALPARS(G_DEBUG) & (1 <<17)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__ );x ;} }
00107  #define   D18(x) { if (GLOBALPARS(G_DEBUG) & (1 <<18)) {x; } ; }
00108  #define MDF18(x) { if (GLOBALPARS(G_DEBUG) & (1 <<18)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__ );x ;} }
00109   #define ELPHEL_DEBUG_THIS 1
00110 #else
00111   #define   MDF(x)
00112   #define   D17(x)
00113   #define MDF17(x)
00114   #define   D18(x)
00115   #define MDF18(x)
00116   #define ELPHEL_DEBUG_THIS 0
00117 #endif
00118 
00119 #define JPEG_HEADER_MAX_SIZE    0x300
00120 static int huffman_fpga_programmed=0;
00122 static struct huff_tables_t {
00123   struct huffman_encoded_t   header_huffman_tables[4]; 
00124   unsigned long              fpga_huffman_table[512];
00125   union {
00126     unsigned char            dht_all[20];
00127     struct {
00128       unsigned char          dht_dc0[5]; 
00129       unsigned char          dht_ac0[5]; 
00130       unsigned char          dht_dc1[5]; 
00131       unsigned char          dht_ac1[5]; 
00132     };
00133   }; 
00134 } huff_tables;
00135 
00136 #define HEADER_COPY_SOF(x) {buf[bpl]=sizeof( x )+8 ; \
00137                             buf[bp++]=sizeof( x)/3; \
00138                             memcpy((void *) &buf[bp], (void *) ( x ), sizeof ( x )); \
00139                             bp+=sizeof ( x );}
00140 #define HEADER_COPY_SOS(x) {buf[bp++]=sizeof( x )+6 ; \
00141                             buf[bp++]=sizeof( x)/2; \
00142                             memcpy((void *) &buf[bp], (void *) ( x ), sizeof ( x )); \
00143                             bp+=sizeof ( x );}
00144 
00150 int qtables_create(struct interframe_params_t * params, unsigned char * buf) {
00151   MDF18(printk("params->quality2=0x%x",params->quality2));
00152   int rslt=get_qtable(params->quality2, &buf[0], &buf[64]); 
00153   if (rslt <0) return rslt; 
00154   return 128;
00155 }
00162 int jpegheader_create(struct interframe_params_t * params, unsigned char * buf) {
00163  int bp=0;   
00164  int bpl;    
00165  int rslt;
00166  int len;
00167  int header_sos; 
00168  const int header_yqtable=    0x19;
00169  const int header_cqtable_hd= 0x59;
00170  const int header_cqtable=    0x5e;
00171  const int header_sof=        0x9e;
00173  const unsigned char jfif1[0x19]={0xff, 0xd8,                   
00174                                   0xff, 0xe0,                   
00175                                   0x00, 0x10,                   
00176                                   0x4a, 0x46, 0x49, 0x46, 0x00, 
00177                                   0x01, 0x01, 0x00, 0x00, 0x01,
00178                                   0x00, 0x01, 0x00, 0x00,
00179                                   0xff, 0xdb,                   
00180                                   0x00, 0x43,                   
00181                                   0x00 };                       
00182 
00183 
00184  const unsigned char jfif2[0x5]= {0xff, 0xdb,                   
00185                                   0x00, 0x43,                   
00186                                   0x01 };                       
00187 
00188  const unsigned char sof_color6[]= {0x01, 0x22, 0x00, 
00189                                     0x02, 0x11, 0x01,
00190                                     0x03, 0x11, 0x01};
00191  const unsigned char sos_color6[]= {0x01, 0x00, 
00192                                     0x02, 0x11,
00193                                     0x03, 0x11};
00194 
00195  const unsigned char sof_jp46dc[]= {0x01, 0x11, 0x00, 
00196                                     0x02, 0x11, 0x00,
00197                                     0x03, 0x11, 0x00,
00198                                     0x04, 0x11, 0x00,
00199                                     0x05, 0x11, 0x01,
00200                                     0x06, 0x11, 0x01};
00201  const unsigned char sos_jp46dc[]= {0x01, 0x00, 
00202                                     0x02, 0x00,
00203                                     0x03, 0x00,
00204                                     0x04, 0x00,
00205                                     0x05, 0x11,
00206                                     0x06, 0x11};
00207 
00208  const unsigned char sof_mono4[]=  {0x01, 0x22, 0x00}; 
00209  const unsigned char sos_mono4[]=  {0x01, 0x00}; 
00210 
00211  const unsigned char sof_jp4[]=    {0x04, 0x22, 0x00}; 
00212  const unsigned char sos_jp4[]=    {0x04, 0x00}; 
00213 
00214  const unsigned char sof_jp4dc[]=  {0x04, 0x11, 0x00, 
00215                                     0x05, 0x11, 0x00,
00216                                     0x06, 0x11, 0x00,
00217                                     0x07, 0x11, 0x00};
00218  const unsigned char sos_jp4dc[]=  {0x04, 0x00, 
00219                                     0x05, 0x00,
00220                                     0x06, 0x00,
00221                                     0x07, 0x00};
00222 
00223  const unsigned char sof_jp4diff[]={0x04, 0x11, 0x11, 
00224                                     0x05, 0x11, 0x11,
00225                                     0x06, 0x11, 0x11,
00226                                     0x07, 0x11, 0x11};
00227  const unsigned char sos_jp4diff[]={0x04, 0x11, 
00228                                     0x05, 0x11,
00229                                     0x06, 0x11,
00230                                     0x07, 0x11};
00231   if (buf==NULL) return -1; 
00232   MDF17(printk("\n"));
00233   MDF18(unsigned char * p= (char *) params; for (len=0;len<32;len++) {if ((len & 0x0f)==0) printk("\n%03x: ",len); printk(" %02x", (int) p[len]);} printk("\n"););
00234 
00235   memcpy((void *) &buf[0],                 (void *) jfif1, sizeof (jfif1)); 
00236   memcpy((void *) &buf[header_cqtable_hd], (void *) jfif2, sizeof (jfif2)); 
00237   rslt=get_qtable(params->quality2, &buf[header_yqtable], &buf[header_cqtable]); 
00238   if (rslt <0) return rslt; 
00239   bp=header_sof;
00240   buf[bp++]=0xff; buf[bp++]=0xc0;
00241   buf[bp++]=0;  
00242   bpl=bp;       
00243   bp++;
00244   buf[bp++]=0x8; 
00245   buf[bp++]=params->height >> 8; buf[bp++]=params->height; 
00246   buf[bp++]=params->width  >> 8; buf[bp++]=params->width;  
00247 
00248   switch (params->color) {
00249    case COLORMODE_MONO6:    
00250    case COLORMODE_COLOR:    
00251    case COLORMODE_COLOR20:  
00252    case COLORMODE_JP46:     
00253      HEADER_COPY_SOF(sof_color6);
00254    break;
00255    case COLORMODE_MONO4:   
00256      HEADER_COPY_SOF(sof_mono4);
00257    break;
00258    case COLORMODE_JP4:     
00259      HEADER_COPY_SOF(sof_jp4);
00260    break;
00261    case COLORMODE_JP46DC:   
00262      HEADER_COPY_SOF(sof_jp46dc);
00263    break;
00264    case COLORMODE_JP4DC:   
00265      HEADER_COPY_SOF(sof_jp4dc);
00266    break;
00267    case COLORMODE_JP4DIFF:   
00268    case COLORMODE_JP4DIFF2:   
00269      HEADER_COPY_SOF(sof_jp4diff);
00270 //header_sof
00271 //bshift
00272      buf[header_sof+12+3*((4-params->byrshift) & 3)]=0; 
00273    break;
00274    case COLORMODE_JP4HDR:   
00275    case COLORMODE_JP4HDR2:   
00276      HEADER_COPY_SOF(sof_jp4diff); 
00277      buf[header_sof+12+3*((4-params->byrshift) & 3)]=0; 
00278      buf[header_sof+12+3*((6-params->byrshift) & 3)]=0; 
00279    break;
00280   }
00282   memcpy((void *) &buf[bp], (void *) huff_tables.dht_dc0, 5); 
00283   bp+=5;
00284   len= (huff_tables.dht_dc0[2]<<8)+huff_tables.dht_dc0[3]-3;  
00285   memcpy((void *) &buf[bp], (void *) &huff_tables.header_huffman_tables[0], len);
00286   bp+=len;
00287 
00288   memcpy((void *) &buf[bp], (void *) huff_tables.dht_ac0, 5); 
00289   bp+=5;
00290   len= (huff_tables.dht_ac0[2]<<8)+huff_tables.dht_ac0[3]-3;  
00291   memcpy((void *) &buf[bp], (void *) &huff_tables.header_huffman_tables[1], len);
00292   bp+=len;
00293 
00294   memcpy((void *) &buf[bp], (void *) huff_tables.dht_dc1, 5); 
00295   bp+=5;
00296   len= (huff_tables.dht_dc1[2]<<8)+huff_tables.dht_dc1[3]-3;  
00297   memcpy((void *) &buf[bp], (void *) &huff_tables.header_huffman_tables[2], len);
00298   bp+=len;
00299 
00300   memcpy((void *) &buf[bp], (void *) huff_tables.dht_ac1, 5); 
00301   bp+=5;
00302   len= (huff_tables.dht_ac1[2]<<8)+huff_tables.dht_ac1[3]-3;  
00303   memcpy((void *) &buf[bp], (void *) &huff_tables.header_huffman_tables[3], len);
00304   bp+=len;
00305 
00307   header_sos=bp;
00308   buf[bp++]=0xff; buf[bp++]=0xda; 
00309   buf[bp++]=0;  
00310   switch (params->color) {
00311    case COLORMODE_MONO6:    
00312    case COLORMODE_COLOR:    
00313    case COLORMODE_COLOR20:  
00314    case COLORMODE_JP46:     
00315      HEADER_COPY_SOS(sos_color6);
00316    break;
00317    case COLORMODE_MONO4:   
00318      HEADER_COPY_SOS(sos_mono4);
00319    break;
00320    case COLORMODE_JP4:     
00321      HEADER_COPY_SOS(sos_jp4);
00322    break;
00323    case COLORMODE_JP46DC:   
00324      HEADER_COPY_SOS(sos_jp46dc);
00325    break;
00326    case COLORMODE_JP4DC:   
00327      HEADER_COPY_SOS(sos_jp4dc);
00328    break;
00329    case COLORMODE_JP4DIFF:   
00330    case COLORMODE_JP4DIFF2:   
00331      HEADER_COPY_SOS(sos_jp4diff);
00332      buf[header_sos+6+2*((4-params->byrshift) & 3)]=0; 
00333    break;
00334    case COLORMODE_JP4HDR:   
00335    case COLORMODE_JP4HDR2:   
00336      HEADER_COPY_SOS(sos_jp4diff); 
00337      buf[header_sos+6+2*((4-params->byrshift) & 3)]=0; 
00338      buf[header_sos+6+2*((6-params->byrshift) & 3)]=0; 
00339    break;
00340   }
00341   buf[bp++]=0x00; 
00342   buf[bp++]=0x3f; 
00343   buf[bp++]=0x00; 
00344   MDF17(printk("JPEG header length=%d\n",bp));
00345   MDF18(for (len=0;len<bp;len++) {if ((len & 0x0f)==0) printk("\n%03x: ",len); printk(" %02x",buf[len]);} printk("\n"););
00346   return bp; 
00347 }
00348 
00349 
00350 
00355 
00356 
00357 
00358 int jpeghead_open(struct inode *inode, struct file *filp) { // set filesize
00359    struct jpeghead_pd * privData;
00360    privData= (struct jpeghead_pd *) kmalloc(sizeof(struct jpeghead_pd),GFP_KERNEL);
00361    if (!privData) return -ENOMEM;
00362    filp->private_data = privData;
00363    privData-> minor=MINOR(inode->i_rdev);
00364    privData-> size=0;                 
00365    inode->i_size=JPEG_HEADER_MAXSIZE; 
00366   return 0;
00367 }
00368 
00384 loff_t  jpeghead_lseek(struct file * file, loff_t offset, int orig){
00385 
00386   int rp;
00387   struct jpeghead_pd * privData;
00388   struct interframe_params_t * fp;
00389   privData = (struct jpeghead_pd *) file->private_data;
00390   MDF17(printk("orig=%d, offst=0x%x\n",orig,(int) offset));
00391 
00392   switch (orig)
00393   {
00394    case SEEK_SET:
00395      file->f_pos = offset;
00396      break;
00397    case SEEK_CUR:
00398      file->f_pos += offset;
00399      break;
00400    case SEEK_END:
00401      if (offset <= 0) {
00402         file->f_pos = privData->size + offset;
00403      } else { 
00404        file->f_pos=0; // anyway reset it to 0
00405        rp= (offset >>2) & (~7); // convert to index to long, align to 32-bytes
00406        fp = (struct interframe_params_t *) &ccam_dma_buf_ptr[X313_BUFFSUB(rp, 8)]; 
00407        if ((fp->signffff != 0xffff) || 
00408           ((fp->timestamp_sec) & X313_LENGTH_MASK)) return -EINVAL; 
00409 
00410 
00411 
00415        if ((offset & 0x1f)==0x2) privData->size= qtables_create(fp, privData->header);    
00416        else                      privData->size= jpegheader_create(fp, privData->header); 
00417        if (privData->size <0 ) {
00418          privData->size=0;
00419          return -EINVAL; 
00420        }
00421        return ( file->f_pos ); 
00422      }
00423      break;
00424    default:
00425      return -EINVAL;
00426   }
00428   if (file->f_pos < 0) {
00429     file->f_pos = 0;
00430     return(-EOVERFLOW);
00431   }
00432 
00433   if (file->f_pos > privData->size) {
00434     file->f_pos = privData->size;
00435   }
00436   return ( file->f_pos );
00437 }
00438 
00439 ssize_t jpeghead_read(struct file * file, char * buf, size_t count, loff_t *off) {
00440   unsigned long p;
00441   struct jpeghead_pd * privData;
00442   privData = (struct jpeghead_pd *) file->private_data;
00443   MDF17(printk("\n"));
00444   p = *off;
00445   if(p >= privData->size)
00446     p = privData->size;
00447     if((p + count) > privData->size) { 
00448         count = privData->size - p;
00449     }
00450     if(count) { 
00451         if(copy_to_user(buf, &privData->header[p], count))  return -EFAULT;
00452         *off += count;
00453     }
00454     return count;
00455 }
00456 
00457 
00466 int huffman_open(struct inode *inode, struct file *filp) { // set filesize
00467    struct huffman_pd * privData;
00468    privData= (struct huffman_pd *) kmalloc(sizeof(struct huffman_pd),GFP_KERNEL);
00469    if (!privData) return -ENOMEM;
00470    filp->private_data = privData;
00471    privData-> minor=MINOR(inode->i_rdev);
00472    inode->i_size = sizeof(huff_tables);
00473 
00474   return 0;
00475 }
00476 
00491 loff_t  huffman_lseek(struct file * file, loff_t offset, int orig){
00492  //  orig 0: position from begning
00493  //  orig 1: relative from current position
00494  //  orig 2: position from last  address
00495 
00496   switch (orig)
00497   {
00498    case SEEK_SET:
00499      file->f_pos = offset;
00500      break;
00501    case SEEK_CUR:
00502      file->f_pos += offset;
00503      break;
00504    case SEEK_END:
00505      if (offset <= 0) {
00506         file->f_pos = sizeof(huff_tables) + offset;
00507      } else { 
00508        switch (offset) {
00509          case LSEEK_HUFFMAN_DC0:     file->f_pos=0; break;
00510          case LSEEK_HUFFMAN_AC0:     file->f_pos=1*sizeof(struct huffman_encoded_t);break;
00511          case LSEEK_HUFFMAN_DC1:     file->f_pos=2*sizeof(struct huffman_encoded_t);break;
00512          case LSEEK_HUFFMAN_AC1:     file->f_pos=3*sizeof(struct huffman_encoded_t);break;
00513          case LSEEK_HUFFMAN_FPGATAB: file->f_pos=4*sizeof(struct huffman_encoded_t);break;
00514          case LSEEK_HUFFMAN_DEFAULT: jpeg_htable_init(); break; // no change to file pointer
00515          case LSEEK_HUFFMAN_FPGACALC:
00516                 if (jpeg_htable_fpga_encode () <0) return -EINVAL;
00517                 break;
00518          case LSEEK_HUFFMAN_FPGAPGM: jpeg_htable_fpga_pgm (); break;
00519          default: return -EINVAL;
00520 
00521        }
00522        return ( file->f_pos );
00523      }
00524      break;
00525    default:
00526      return -EINVAL;
00527   }
00528   // truncate position
00529   if (file->f_pos < 0) {
00530     file->f_pos = 0;
00531     return(-EOVERFLOW);
00532   }
00533   if (file->f_pos > sizeof(huff_tables)) file->f_pos = sizeof(huff_tables);
00534   return ( file->f_pos );
00535 }
00536 
00537 
00538 ssize_t huffman_read(struct file * file, char * buf, size_t count, loff_t *off) {
00539   unsigned long p;
00540   unsigned char * uc_huff_tables= (unsigned char *) &huff_tables; 
00541   MDF17(printk("\n"));
00542   p = *off;
00543   if(p >= sizeof(huff_tables))  p = sizeof(huff_tables);
00544   if((p + count) > sizeof(huff_tables)) count = sizeof(huff_tables) - p; 
00545   if(count) { 
00546     if(copy_to_user(buf, &uc_huff_tables[p], count)) return -EFAULT;
00547     *off += count;
00548   }
00549   return count;
00550 }
00551 
00552 
00553 ssize_t huffman_write(struct file * file, const char * buf, size_t count, loff_t *off) {
00554   unsigned long p;
00555   unsigned char * uc_huff_tables= (unsigned char *) &huff_tables; 
00556   MDF17(printk("\n"));
00557   p = *off;
00558   if (p >= sizeof(huff_tables))  p = sizeof(huff_tables);
00559   if( (p + count) > sizeof(huff_tables)) count = sizeof(huff_tables) - p; 
00560   if (count) { 
00561     if (copy_from_user(&uc_huff_tables[p],buf, count)) return -EFAULT;
00562   }
00563 
00564   return count;
00565 }
00566 
00570 void jpeg_htable_init (void) {
00571   unsigned char dc0[]={0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
00572                        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
00573                        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
00574                        0x08, 0x09, 0x0a, 0x0b};
00575 
00576   unsigned char ac0[]={0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
00577                        0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 
00578                        0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 
00579                        0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
00580                        0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
00581                        0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
00582                        0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
00583                        0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
00584                        0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
00585                        0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
00586                        0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
00587                        0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
00588                        0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
00589                        0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
00590                        0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
00591                        0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
00592                        0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
00593                        0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
00594                        0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
00595                        0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
00596                        0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
00597                        0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
00598                        0xf9, 0xfa};
00599 
00600   unsigned char dc1[]={0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00601                        0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
00602                        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
00603                        0x08, 0x09, 0x0a, 0x0b};
00604   unsigned char ac1[]={0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
00605                        0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
00606                        0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
00607                        0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
00608                        0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
00609                        0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
00610                        0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
00611                        0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
00612                        0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
00613                        0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
00614                        0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
00615                        0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
00616                        0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
00617                        0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
00618                        0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
00619                        0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
00620                        0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
00621                        0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
00622                        0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
00623                        0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
00624                        0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
00625                        0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
00626                        0xf9, 0xfa};
00627    MDF17(printk(" started\n"));
00628   memset ((void*) &huff_tables,0, sizeof(huff_tables));
00629   memcpy ((void*) huff_tables.header_huffman_tables[0].bits,dc0, sizeof(dc0));
00630   memcpy ((void*) huff_tables.header_huffman_tables[1].bits,ac0, sizeof(ac0));
00631   memcpy ((void*) huff_tables.header_huffman_tables[2].bits,dc1, sizeof(dc1));
00632   memcpy ((void*) huff_tables.header_huffman_tables[3].bits,ac1, sizeof(ac1));
00633    MDF17(printk("jpeg_htable_fpga_encode ()\n"));
00634   jpeg_htable_fpga_encode ();
00635 }
00636 
00643 int jpeg_htable_fpga_encode (void) {
00644   int ntab, i, rslt, a, length;
00645   const unsigned char dht_headers[20]={ 
00646       0xff, 0xc4, 0x00, 0x00, 0x00,
00647       0xff, 0xc4, 0x00, 0x00, 0x10,
00648       0xff, 0xc4, 0x00, 0x00, 0x01,
00649       0xff, 0xc4, 0x00, 0x00, 0x11 };
00650   struct huffman_fpga_code_t codes[256];
00651   unsigned long * icodes = (unsigned long *) codes;
00652   huffman_fpga_programmed=0; 
00653    MDF17(printk(" started\n"));
00655   memcpy ((void*) huff_tables.dht_all, (void*) dht_headers, sizeof(dht_headers)); 
00656   for (ntab=0; ntab<4; ntab++) {
00657      MDF17(printk("ntab=%d\n", ntab));
00658     memset (codes,0,sizeof(codes));
00659     if ((rslt=jpeg_prep_htable (&(huff_tables.header_huffman_tables[ntab]), codes)) < 0 ) return rslt;
00660     if (ntab & 1) {
00661       a=((ntab & 2)<<7);
00662       for (i=0; i<256;i+=16) {
00663         memcpy ((void*) &(huff_tables.fpga_huffman_table[a]), (void*) &codes[i], 60); 
00664         a+=16;
00665       }
00666     } else {
00667       a=((ntab & 2)<<7)+0x0f; 
00668       for (i=0; i<16;i++) {
00669         huff_tables.fpga_huffman_table[a]= icodes[i];
00670         a+=16;
00671       }
00672     }
00674     length=19; 
00675     for (i=0; i<16; i++) length += huff_tables.header_huffman_tables[ntab].bits[i]; 
00676     huff_tables.dht_all[(5*ntab)+2]=length >> 8;  
00677     huff_tables.dht_all[(5*ntab)+3]=length& 0xff; 
00678   }
00679 
00680   MDF17(printk("\nFPGA Huffman table\n");for (i=0;i<512;i++){printk (" %06x",(int)huff_tables.fpga_huffman_table[i]); if ((i & 0x0f)==0x0f) printk("\n");});
00681   return 0;
00682 }
00683 
00684 
00689 int  jpeg_htable_is_programmed(void) {
00690  return huffman_fpga_programmed;
00691 }
00692 
00696 void jpeg_htable_fpga_pgm (void) {
00697   fpga_table_write_nice (CX313_FPGA_TABLES_HUFF, 512, huff_tables.fpga_huffman_table);
00698   huffman_fpga_programmed=1;
00699 }
00700 
00702 
00708 
00709 int jpeg_prep_htable (struct huffman_encoded_t * htable, struct huffman_fpga_code_t * hcodes) {
00710   int p, i, l, si, numsymbols;
00711   unsigned int code;
00712    MDF17(printk(" started\n"));
00714   p = 0;
00715   for (l = 1; l <= 16; l++) {
00716     i = htable->bits[l-1];
00717     if (i < 0 || p + i > 256) {
00718         MDF17(printk("protect against table overrun\n"));
00719        return -1 ; 
00720     }
00721     while (i--) hcodes[htable->huffval[p++]].length=l;
00722   }
00723   numsymbols = p;
00726   code = 0;
00727   si = hcodes[htable->huffval[0]].length;
00728   p = 0;
00730   while (p < numsymbols) {
00731     if ((hcodes[htable->huffval[p]].length < si) || (si>16)) {
00732        ELP_KERR(printk("Bad table/bug\n"));
00733       return -3; 
00734     }
00735     while (hcodes[htable->huffval[p]].length == si) {
00736       hcodes[htable->huffval[p++]].value = code;
00737       code++;
00738     }
00739 
00743     if ( code >= (1 << si)) {
00744        ELP_KERR(printk("Bad code\n"));
00745       return -2; 
00746     }
00747     code <<= 1;
00748     si++;
00749   }
00750   return 0;
00751 }
00752 

Generated on Fri Nov 28 00:06:23 2008 for elphel by  doxygen 1.5.1