00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
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
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"
00092 #include "jpeghead.h"
00093 #include "fpgactrl.h"
00094 #include "framepars.h"
00095 #include "quantization_tables.h"
00096 #include "x3x3.h"
00097
00098 #include "cxdma.h"
00099
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
00271
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) {
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;
00405 rp= (offset >>2) & (~7);
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) {
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
00493
00494
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;
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
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