pdv_interlace.c

Go to the documentation of this file.
00001 
00007 #include "edtinc.h"
00008 
00009 #include "pdv_interlace_methods.h"
00010 
00011 /*********************************************/
00012 /* Bayer Filter interpolation code           */
00013 /*********************************************/
00014 
00015 #ifdef USE_MMX
00016 
00017 #include "bayer_filter_asm.h"
00018 
00019 #endif
00020 
00021 
00022 #include <math.h>
00023 /* shorthand debug level */
00024 
00025 #define PDVWARN PDVLIB_MSG_WARNING
00026 #define PDVFATAL PDVLIB_MSG_FATAL
00027 #define DBG1 PDVLIB_MSG_INFO_1
00028 #define DBG2 PDVLIB_MSG_INFO_2
00029 
00030 #define PDV_BAYER_ORDER_BGGR 0
00031 #define PDV_BAYER_ORDER_GBRG 1
00032 #define PDV_BAYER_ORDER_RGGB 2
00033 #define PDV_BAYER_ORDER_GRBG 3
00034 
00035 #define PDV_BAYER_ORDER(dd_p) ((((Dependent *) dd_p)->kbs_red_row_first << 1) \
00036     | ((Dependent *) dd_p)->kbs_green_pixel_first)
00037 
00038 
00039 
00040 
00041 
00042 static int
00043 pdv_default_interlace_inplace(int interlace_type)
00044 
00045 {
00046 #ifdef USE_MMX
00047     if (interlace_type == 0 || 
00048         interlace_type == PDV_BYTE_INTLV ||
00049         /* interlace_type == PDV_PIRANHA_4CH_INTLV || */
00050         interlace_type == PDV_INTLV_BGR_2_RGB)
00051 #else
00052     if (interlace_type == 0)
00053 #endif
00054     {
00055         return 1;
00056     }
00057 
00058     return 0;
00059 
00060 }
00061 
00062 int
00063 pdv_process_inplace(PdvDev *pdv_p)
00064 {
00065     EdtPostProc *pCntl;
00066 
00067     if ((pCntl = (EdtPostProc *) pdv_p->pInterleaver))
00068     {
00069         if (pCntl->doinplace)
00070             return pCntl->doinplace();
00071 
00072     }
00073 
00074     return pdv_default_interlace_inplace(pdv_p->dd_p->swinterlace);
00075 }
00076 
00077 
00078 void
00079 pdv_alloc_tmpbuf(PdvDev * pdv_p)
00080 
00081 {
00082     Dependent *dd_p = pdv_p->dd_p;
00083 
00084 
00085     if (dd_p->swinterlace)
00086     {
00087         int     size = pdv_get_dmasize(pdv_p);
00088 
00089         if (dd_p->imagesize > size)
00090             size = dd_p->imagesize;
00091 
00092         if (size != (int) pdv_p->tmpbufsize)
00093         {
00094             if (pdv_p->tmpbuf)
00095                 edt_free(pdv_p->tmpbuf);
00096 
00097             if (size)
00098             {
00099                 pdv_p->tmpbuf = edt_alloc(size);
00100             }
00101             else
00102                 pdv_p->tmpbuf = NULL;
00103 
00104             pdv_p->tmpbufsize = size;
00105 
00106         }
00107     }
00108 }
00109 
00110 
00111 
00112 /* byte -> byte */
00113 
00114 int
00115 deIntlv_ES10_8(u_char * src, int width, int rows, u_char * dest)
00116 {
00117 
00118 
00119 
00120 #ifdef USE_MMX
00121 
00122     if (bayer_can_use_mmx())
00123     {
00124         edt_msg(DBG2, "Using MMX\n");
00125         return deIntlv_ES10_8_mmx_inplace(src, width, rows, dest);
00126 
00127     }
00128     else
00129 
00130 #endif
00131     {
00132         u_char *even_dst;
00133         u_char *odd_dst;
00134         int     x, y;
00135 
00136         edt_msg(DBG2, "ES10deInterLeave()\n");
00137 
00138         even_dst = dest;
00139         odd_dst = dest + width;
00140 
00141         for (y = 0; y + 1 < rows; y += 2)
00142         {
00143             for (x = 0; x < width; x++)
00144             {
00145                 *even_dst++ = *src++;
00146                 *odd_dst++ = *src++;
00147             }
00148             even_dst += width;
00149             odd_dst += width;
00150         }
00151     }
00152     return (0);
00153 }
00154 
00155 
00156 /*
00157 * words are arranged in source as row0pix0, row1,pix0, row0pix1, row1pix1
00158 */
00159 int
00160 deIntlv_ES10_16(u_short * src, int width, int rows, u_short * dest)
00161 {
00162     u_short *even_dst;
00163     u_short *odd_dst;
00164     int     x, y;
00165 
00166     edt_msg(DBG2, "ES10_word_deIntlv()\n");
00167 
00168     even_dst = dest;
00169     odd_dst = dest + width;
00170 
00171     for (y = 0; y < rows; y += 2)
00172     {
00173         for (x = 0; x < width; x++)
00174         {
00175             *even_dst++ = *src++;
00176             *odd_dst++ = *src++;
00177         }
00178         even_dst += width;
00179         odd_dst += width;
00180     }
00181     return (0);
00182 }
00183 
00184 /*
00185 * same as ES10_word_deIntlv but odd line first
00186 */
00187 int
00188 deIntlv_ES10_16_odd(u_short * src, int width, int rows, u_short * dest)
00189 {
00190     u_short *even_dst;
00191     u_short *odd_dst;
00192     int     x, y;
00193 
00194     edt_msg(DBG2, "ES10_word_deIntlv_odd()\n");
00195 
00196     odd_dst = dest;
00197     even_dst = dest + width;
00198 
00199     for (y = 0; y < rows; y += 2)
00200     {
00201         for (x = 0; x < width; x++)
00202         {
00203             *even_dst++ = *src++;
00204             *odd_dst++ = *src++;
00205         }
00206         odd_dst += width;
00207         even_dst += width;
00208     }
00209     return (0);
00210 }
00211 
00212 /*
00213 * word deinterleave to two images one above the other
00214 */
00215 int
00216 deIntlv_ES10_16_hilo(u_short * src, int width, int rows, u_short * dest)
00217 {
00218     u_short *even_dst;
00219     u_short *odd_dst;
00220     int     x, y;
00221 
00222     edt_msg(DBG2, "ES10_word_deIntlv_hilo()\n");
00223 
00224     even_dst = dest;
00225     odd_dst = dest + (width * (rows / 2));
00226 
00227     for (y = 0; y < rows; y += 2)
00228     {
00229         for (x = 0; x < width; x++)
00230         {
00231             *even_dst++ = *src++;
00232             *odd_dst++ = *src++;
00233         }
00234     }
00235     return (0);
00236 }
00237 
00238 /*
00239 * byte deinterleave top down / bottom up 
00240 */
00241 int
00242 deIntlv_TopBottom8(u_char * src, int width, int rows, u_char * dest)
00243 {
00244     u_char *even_dst;
00245     u_char *odd_dst;
00246     int     x, y;
00247 
00248     edt_msg(DBG2, "deIntlv_TopBottom8()\n");
00249 
00250     even_dst = dest;
00251     odd_dst = dest + (width * (rows-1));
00252 
00253     for (y = 0; y < rows; y += 2)
00254     {
00255         for (x = 0; x < width; x++)
00256         {
00257             *even_dst++ = *src++;
00258             *odd_dst++ = *src++;
00259         }
00260         odd_dst -= width*2;
00261     }
00262     return (0);
00263 }
00264 
00265 /*
00266 * word deinterleave top down / bottom up 
00267 */
00268 int
00269 deIntlv_TopBottom16(u_short * src, int width, int rows, u_short * dest)
00270 {
00271     u_short *even_dst;
00272     u_short *odd_dst;
00273     int     x, y;
00274 
00275     edt_msg(DBG2, "deIntlv_TopBottom16()\n");
00276 
00277     even_dst = dest;
00278     odd_dst = dest + (width * (rows-1));
00279 
00280     for (y = 0; y < rows; y += 2)
00281     {
00282         for (x = 0; x < width; x++)
00283         {
00284             *even_dst++ = *src++;
00285             *odd_dst++ = *src++;
00286         }
00287         odd_dst -= width*2;
00288     }
00289     return (0);
00290 }
00291 
00292 /*
00293 * byte deinterleave from the center out horizontally
00294 */
00295 int
00296 deIntlv_InOut8(u_char * src, int width, int rows, u_char * dest)
00297 {
00298     u_char *even_dst;
00299     u_char *odd_dst;
00300     int     x, y;
00301 
00302     edt_msg(DBG2, "deIntlv_InOut8()\n");
00303 
00304     for (y = 0; y < rows; y ++)
00305     {
00306         odd_dst = dest + (width / 2);
00307         even_dst = odd_dst - 1;
00308         for (x = 0; x < width; x++)
00309         {
00310             *even_dst-- = *src++;
00311             *odd_dst++ = *src++;
00312         }
00313         dest += width;
00314     }
00315     return (0);
00316 }
00317 
00318 /*
00319 * word deinterleave from the center out horizontally
00320 */
00321 int
00322 deIntlv_InOut16(u_short * src, int width, int rows, u_short * dest)
00323 {
00324     u_short *even_dst;
00325     u_short *odd_dst;
00326     int     x, y;
00327 
00328     edt_msg(DBG2, "deIntlv_InOut16()\n");
00329 
00330     for (y = 0; y < rows; y ++)
00331     {
00332         odd_dst = dest + (width / 2);
00333         even_dst = odd_dst - 1;
00334         for (x = 0; x < width; x++)
00335         {
00336             *even_dst-- = *src++;
00337             *odd_dst++ = *src++;
00338         }
00339         dest += width;
00340     }
00341     return (0);
00342 }
00343 
00344 
00345 /*
00346 * piranha/atmel m4 8 bit deinterleave -- lhs side normal, rhs in from left and swapped
00347 */
00348 int
00349 deIntlv_piranha_8(u_char *src, int width, int rows, u_char *dest)
00350 
00351 {
00352     int x, y;
00353     u_char *sx=src;
00354     u_char *dxl, *dxr;
00355 
00356     edt_msg(DBG2, "deIntlv_piranha_8()\n");
00357 
00358     for (y=0;y<rows;y++)
00359     {
00360         dxl = dest + (width * y);
00361         dxr = (dxl + width) - 1;
00362         for (x=0;x<width;x+=4)
00363         {
00364             *(dxl++)  = *(sx++);
00365             *(dxl++)  = *(sx++);
00366             *(dxr-1)  = *(sx++);        /* rhs gets swapped */
00367             *(dxr)    = *(sx++);
00368             dxr -= 2;
00369         }
00370     }
00371     return (0);
00372 }
00373 
00374 /*
00375 * words are arranged in source as row0pix0, row1,pix0, row0pix1, row1pix1
00376 */
00377 int
00378 deIntlv_dalsa_4ch_8(u_char * src, int width, int rows, u_char * dest)
00379 {
00380     int     x, y;
00381     int     dx = 0;
00382     int     swidth = width / 4 - 1;
00383     u_char *sp = src;
00384 
00385     edt_msg(DBG2, "deIntlv_dalsa_4ch_8() -- %d pixel bands\n", swidth);
00386 
00387     sp = src;
00388     for (y = 0; y < rows; y++)
00389     {
00390         dx = y * width;
00391         for (x = 0; x < width / 4; x++, dx++)
00392         {
00393             dest[dx] = *sp++;
00394             dest[dx + swidth] = *sp++;
00395             dest[dx + (swidth * 2)] = *sp++;
00396             dest[dx + (swidth * 3)] = *sp++;
00397         }
00398     }
00399     return (0);
00400 }
00401 
00402 
00403 /*
00404 * 4 port spectral instruments upper left, upper right, lower left, lower
00405 * right, moving in to the center 2 bytes per pixel
00406 */
00407 int
00408 deIntlv_specinst_4ch_16(u_short * src, int width, int rows, u_short * dest)
00409 {
00410     int     x, y;
00411     int     dxul, dxur, dxll, dxlr;
00412     u_short *sp = src;
00413 
00414     edt_msg(DBG2, "deIntlv_specinst_4ch_16()\n");
00415 
00416     for (y = 0; y < rows / 2; y++)
00417     {
00418         dxul = y * width;
00419         dxur = dxul + (width - 1);
00420         dxll = (width * ((rows - y) - 1));
00421         dxlr = dxll + (width - 1);
00422         for (x = 0; x < width / 2; x++)
00423         {
00424             dest[dxll++] = *sp++;
00425             dest[dxlr--] = *sp++;
00426             dest[dxul++] = *sp++;
00427             dest[dxur--] = *sp++;
00428         }
00429     }
00430     return (0);
00431 }
00432 
00433 int
00434 deIntlv_quad_16(u_short *src, int width, int rows, u_short *dest)
00435 {
00436     int i,r,c, nrows,ncols,qrows,qcols;
00437 
00438     edt_msg(DBG2, "deIntlv_quad_16\n");
00439 
00440     nrows = rows;
00441     ncols = width;
00442     qrows = nrows>>1;
00443     qcols = ncols>>1;
00444 
00445     for (r = 0,i = 0; r < qrows*ncols; r += ncols)
00446         for (c = 0; c < qcols; ++c, i += 4)
00447             dest[r+c] = src[i];
00448     for (r = 0,i = 1; r < qrows*ncols; r += ncols)
00449         for (c = ncols-1; c >= qcols; --c, i += 4)
00450             dest[r+c] = src[i];
00451     for (r = (nrows-1)*ncols,i = 2; r >= qrows*ncols; r -= ncols)
00452         for (c = 0; c < qcols; ++c, i += 4)
00453             dest[r+c] = src[i];
00454     for (r = (nrows-1)*ncols,i = 3; r >= qrows*ncols; r -= ncols)
00455         for (c = ncols-1; c >= qcols; --c, i += 4)
00456             dest[r+c] = src[i];
00457     return (0);
00458 }
00459 
00460 /*****************************************/
00461 /* 4 port deinterleave                   */
00462 /*****************************************/
00463 
00464 int
00465 deIntlv_4ch_ill_16(u_short *src, int width, int height, u_short *dest)
00466 {
00467     int x, y, qwidth, qheight;
00468     u_short *ul, *ur, *ll, *lr;
00469     u_short *sp = src;
00470 
00471     edt_msg(DBG2, "deIntlv_4ch_ill_16\n");
00472 
00473     qwidth = width/2;
00474     qheight = height/2;
00475 
00476     for (y=0; y<qheight; y++)
00477     {
00478         ul = dest + (y * width);
00479         ur = ul + width - 1;
00480         ll = dest + ((height - y) - 1) * width;
00481         lr = ll + width - 1;
00482 
00483         for (x=0; x<qwidth; x++)
00484         {
00485             *(lr-x) = *sp++;
00486             *(ur-x) = *sp++;
00487             *(ll+x) = *sp++;
00488             *(ul+x) = *sp++;
00489         }
00490     }
00491 
00492     return (0);
00493 }
00494 
00495 int
00496 deIntlv_4ch_ill_8(u_char *src, int width, int height, u_char *dest)
00497 {
00498     int x, y, qwidth, qheight;
00499     u_char *ul, *ur, *ll, *lr;
00500     u_char *sp = src;
00501 
00502     edt_msg(DBG2, "deIntlv_4ch_ill_8\n");
00503 
00504     qwidth = width/2;
00505     qheight = height/2;
00506 
00507     for (y=0; y<qheight; y++)
00508     {
00509         ul = dest + (y * width);
00510         ur = ul + width - 1;
00511         ll = dest + ((height - y) - 1) * width;
00512         lr = ll + width - 1;
00513 
00514         for (x=0; x<qwidth; x++)
00515         {
00516             *(ul+x) = *sp++;
00517             *(ll+x) = *sp++;
00518             *(ur-x) = *sp++;
00519             *(lr-x) = *sp++;
00520         }
00521     }
00522 
00523     return (0);
00524 }
00525 
00526 
00527 
00528 int
00529 deintlv_line_taps_8x4(u_char *src, int width, int rows, u_char *dest, int ntaps, PdvInterleaveTap *taps)
00530 
00531 {
00532     int i0, i1, i2, i3, x;
00533 
00534     int row;
00535     u_char *sp, *dp;
00536 
00537     static int last_alloc = 0;
00538 
00539     static u_char * line_buffer;
00540 
00541     if (width != last_alloc)
00542     {
00543         line_buffer = edt_alloc(width);
00544         last_alloc = width;
00545     }
00546 
00547     sp = src;
00548     dp = dest;
00549 
00550     for (row = 0;row < rows;row ++)
00551     {
00552         i0 = taps[0].startx;
00553         i1 = taps[1].startx;
00554         i2 = taps[2].startx;
00555         i3 = taps[3].startx;
00556         for (x = 0; x < width;x += 4)
00557         {
00558             line_buffer[i0] = sp[x];
00559             line_buffer[i1] = sp[x+1];
00560             line_buffer[i2] = sp[x+2];
00561             line_buffer[i3] = sp[x+3];
00562 
00563             i0 += taps[0].dx;
00564             i1 += taps[1].dx;
00565             i2 += taps[2].dx;
00566             i3 += taps[3].dx;
00567         }
00568 
00569         memcpy(dp, line_buffer, width);
00570         sp += width;
00571         dp += width;
00572 
00573     }
00574 
00575     return 0;
00576 
00577 }
00578 
00579 /*
00580 * dalsa p3 linescan, 4 taps 8 bit arranged with taps 0 & 1 = 1st and 2nd quarter of data,
00581 *  taps 2 & 3 are 3rd and 4th quarter of data inverted right-left
00582 */
00583 int
00584 deIntlv_line_taps_8x4_inv_rt(u_char * src, int width, int rows, u_char * dest)
00585 {
00586     int i, y, t1, t2, t3, t4;
00587     int offs2 = width/4;
00588     int offs3 = ((width/4)*3) - 1;
00589     int offs4 = width-1;
00590 
00591     static int last_alloc = 0;
00592     static u_char * line_buffer;
00593 
00594     u_char *sp = src;
00595     u_char *dp = dest;
00596 
00597     if (width != last_alloc)
00598     {
00599         line_buffer = edt_alloc(width);
00600         last_alloc = width;
00601     }
00602 
00603     for (y=0; y<rows; y++)
00604     {
00605         t1 = 0;
00606         t2 = offs2;
00607         t3 = offs3;
00608         t4 = offs4;
00609 
00610         for (i=0; i<width; i+=4)
00611         {
00612             line_buffer[t1++] = *(sp++);
00613             line_buffer[t2++] = *(sp++);
00614             line_buffer[t3--] = *(sp++);
00615             line_buffer[t4--] = *(sp++);
00616         }
00617         memcpy(dp, line_buffer, width);
00618         dp += width;
00619     }
00620 
00621     return (0);
00622 }
00623 
00624 
00631 int
00632 deIntlv_2ch_inv_rt_24_12(u_char * src, 
00633                          int width, 
00634                          int rows, 
00635                          u_short * dest)
00636 {
00637     int     y;
00638     u_short *lp, *rp;
00639     u_char *sp = src;
00640 
00641 
00642 #if 0
00643 #ifdef USE_MMX
00644 
00645     if (bayer_can_use_mmx())
00646     {
00647         edt_msg(DBG2, "Using MMX\n");
00648         return Inv_Rt_2ch_deIntlv_2ch_24_12_mmx(src, width, rows, dest);
00649 
00650     }
00651 #endif
00652 #endif
00653 
00654     for (y = 0; y < rows; y++)
00655     {
00656         lp = dest + (y * width);
00657         rp = lp + width - 1;
00658 
00659         while (lp < rp)
00660         {
00661             *rp-- = sp[0] + ((sp[1] & 0xf0) << 4);
00662             *lp++ = sp[2] + ((sp[1] & 15) << 8);
00663 
00664             sp += 3;
00665         }
00666     }
00667     return (0);
00668 }
00669 
00676 int
00677 deIntlv_2ch_24_12(u_char * src, 
00678                   int width, 
00679                   int rows, 
00680                   u_short * dest)
00681 {
00682     int     x, y;
00683     u_short *lp;
00684     u_char *sp = src;
00685 
00686 
00687     for (y = 0; y < rows; y++)
00688     {
00689 
00690         lp = dest + (y * width);
00691 
00692         for (x = 0; x < width-1; x +=2)
00693         {
00694             lp[x] = sp[0] + ((sp[1] & 0xf0) << 4);
00695             lp[x+1] = sp[2] + ((sp[1] & 15) << 8);
00696             sp += 3;
00697         }
00698     }
00699     return (0);
00700 }
00701 
00702 
00703 int
00704 deIntlv_1_8_msb7(u_char * src, 
00705                  int width, 
00706                  int rows, 
00707                  u_char * dest)
00708 {
00709     int     x, y;
00710     u_char *lp;
00711     u_char *sp = src;
00712 
00713     for (y = 0; y < rows; y++)
00714     {
00715 
00716         lp = dest + (y * width);
00717 
00718         for (x = 0; x < width-7; x += 8)
00719         {
00720             lp[x]   = (sp[0] & 0x80) ? 255:0;
00721             lp[x+1] = (sp[0] & 0x40) ? 255:0;
00722             lp[x+2] = (sp[0] & 0x20) ? 255:0;
00723             lp[x+3] = (sp[0] & 0x10) ? 255:0;
00724             lp[x+4] = (sp[0] & 0x8)  ? 255:0;
00725             lp[x+5] = (sp[0] & 0x4)  ? 255:0;
00726             lp[x+6] = (sp[0] & 0x2)  ? 255:0;
00727             lp[x+7] = (sp[0] & 0x1)  ? 255:0;
00728 
00729             sp ++;
00730         }
00731     }
00732     return (0);
00733 }
00734 
00739 int
00740 deIntlv_1_8_msb0(u_char * src, 
00741                  int width, 
00742                  int rows, 
00743                  u_char * dest)
00744 {
00745     int     x, y;
00746     u_char *lp;
00747     u_char *sp = src;
00748 
00749 
00750     for (y = 0; y < rows; y++)
00751     {
00752 
00753         lp = dest + (y * width);
00754 
00755         for (x = 0; x < width-7; x += 8)
00756         {
00757             lp[x]   = (sp[0] & 0x1)  ? 255:0;
00758             lp[x+1] = (sp[0] & 0x2)  ? 255:0;
00759             lp[x+2] = (sp[0] & 0x4)  ? 255:0;
00760             lp[x+3] = (sp[0] & 0x8)  ? 255:0;
00761             lp[x+4] = (sp[0] & 0x10) ? 255:0;
00762             lp[x+5] = (sp[0] & 0x20) ? 255:0;
00763             lp[x+6] = (sp[0] & 0x40) ? 255:0;
00764             lp[x+7] = (sp[0] & 0x80) ? 255:0;
00765 
00766             sp ++;
00767         }
00768     }
00769     return (0);
00770 }
00771 
00772 /*
00773 * channel 0 is first half of line, channel 1 is second half reversed
00774 (will work in place) 
00775 
00776 */
00777 int
00778 deIntlv_inv_rt_8(u_char * src, int width, int rows, u_char * dest)
00779 {
00780     int     y;
00781     u_char *lp, *rp;
00782     u_char *sp = src;
00783 
00784     u_char *line_buffer;
00785 
00786     /* use line buffer to be able to do in place */
00787 
00788     line_buffer = edt_alloc(width);
00789 
00790     edt_msg(DBG2, "inv_rt_deIntlv()\n");
00791 
00792     for (y = 0; y < rows; y++)
00793     {
00794         lp = line_buffer;
00795         rp = lp + width - 1;
00796         while (lp < rp)
00797         {
00798             *lp++ = *sp++;
00799             *rp-- = *sp++;
00800         }
00801         memcpy(dest + (y * width), line_buffer, width);
00802 
00803     }
00804 
00805     edt_free(line_buffer);
00806 
00807     return (0);
00808 }
00809 
00810 /*
00811 * channel 0 is first half of line, channel 1 is second half reversed
00812 (will work in place) 
00813 */
00814 int
00815 deIntlv_inv_rt_16(u_short * src, int width, int rows, u_short * dest)
00816 {
00817     int     y;
00818     u_short *lp, *rp;
00819     u_short *sp = src;
00820     u_short *line_buffer;
00821 
00822     edt_msg(DBG2, "deIntlv_inv_rt_16()\n");
00823 
00824 
00825     line_buffer = (u_short *) edt_alloc(width * sizeof(u_short));
00826 
00827     if (!line_buffer)
00828         return -1;
00829 
00830     for (y = 0; y < rows; y++)
00831     {
00832         lp = line_buffer;
00833         rp = lp + width - 1;
00834         while (lp < rp)
00835         {
00836             *lp++ = *sp++;
00837             *rp-- = *sp++;
00838         }
00839 
00840         memcpy(dest + y * width, 
00841             line_buffer, 
00842             width * sizeof(u_short));
00843 
00844     }
00845 
00846     edt_free((unsigned char *)line_buffer);
00847 
00848     return (0);
00849 }
00850 
00851 
00852 /*
00853 * channel 0 is first half of line, channel 1 is second half reversed
00854 (will work in place) 
00855 */
00856 int
00857 deIntlv_inv_rt_16_BGR(u_short * src, 
00858                       int width, int rows, 
00859                       u_char * dest,
00860                       int order,
00861                       int src_depth)
00862 {
00863     int rc;
00864 
00865     if ((rc = deIntlv_inv_rt_16(src, width, rows, src)) == 0)
00866     {
00867 
00868         return convert_bayer_image_16_BGR(src, width, rows,  width, dest,
00869             order, src_depth);
00870     }
00871     else
00872         return rc;
00873 }
00874 
00875 /*
00876 * channel 0 is first half of line, channel 1 is second half
00877 */
00878 int
00879 deIntlv_inv_rt_8_BGR(u_char * src, int width, 
00880                      int rows, 
00881                      u_char * dest,
00882                      int order)
00883 {
00884     int rc;
00885 
00886     if ((rc = deIntlv_inv_rt_8(src, width, rows, src)) == 0)
00887     {
00888 
00889         return convert_bayer_image_8_BGR(src, width, rows,  width, dest,
00890             order);
00891     }
00892     else
00893         return rc;
00894 }
00895 
00896 /*
00897 * channel 0 is first half of line, channel 1 is second half
00898 */
00899 int
00900 deIntlv_2ch_even_rt_8(u_char * src, int width, int rows, u_char * dest)
00901 {
00902     int     y;
00903     u_char *lp, *rp, *ep;
00904     u_char *sp = src;
00905 
00906     edt_msg(DBG2, "deIntlv_2ch_even_rt_8()\n");
00907 
00908     for (y = 0; y < rows; y++)
00909     {
00910         lp = dest + (y * width);
00911         rp = lp + (width / 2);
00912         ep = lp + width ;
00913         while (rp < ep)
00914         {
00915             *lp++ = *sp++;
00916             *rp++ = *sp++;
00917         }
00918     }
00919     return (0);
00920 }
00921 /*
00922 * channel 0 is first half of line, channel 1 is second half
00923 */
00924 int
00925 deIntlv_2ch_even_rt_16(u_short * src, int width, int rows, u_short * dest)
00926 {
00927     int     y;
00928     u_short *lp, *rp, *ep;
00929     u_short *sp = src;
00930 
00931     edt_msg(DBG2, "deIntlv_2ch_even_rt_816()\n");
00932 
00933     for (y = 0; y < rows; y++)
00934     {
00935         lp = dest + (y * width);
00936         rp = lp + (width / 2);
00937         ep = lp + width ;
00938         while (rp < ep)
00939         {
00940             *lp++ = *sp++;
00941             *rp++ = *sp++;
00942         }
00943     }
00944     return (0);
00945 }
00946 
00947 /*
00948 * merges image which is split into odd,even fields to destination
00949 */
00950 int
00951 deIntlv_merge_fields(
00952                      u_char * evenptr,
00953                      u_char * oddptr,
00954                      int width,
00955                      int rows,
00956                      int depth,
00957                      u_char * dest,
00958                      int offset
00959                      )
00960 {
00961     int     depth_bytes = ((int) depth + 7) / 8;
00962     int     partial = 0;
00963 
00964     edt_msg(DBG2, "deIntlv_merge_fields() interlace %d offset %d\n",
00965         oddptr - evenptr, offset);
00966 
00967     width *= depth_bytes;
00968 
00969     /* what should we do with odd number of rows? */
00970     if (rows & 1)
00971         rows--;
00972 
00973     /* first line may be partial */
00974     if (offset)
00975     {
00976         partial = 2;
00977         offset *= depth_bytes;
00978         memset(dest, 0, offset);
00979         memcpy(dest + offset, evenptr, width - offset);
00980         dest += width;
00981         evenptr += width - offset;
00982 
00983         memcpy(dest, oddptr, width);
00984         dest += width;
00985         oddptr += width;
00986 
00987         rows -= 2;
00988     }
00989 
00990     for (; rows > partial; rows -= 2)
00991     {
00992         /* Zeroth line is at start of even field */
00993         memcpy(dest, evenptr, width);
00994         dest += width;
00995         evenptr += width;
00996 
00997         memcpy(dest, oddptr, width);
00998         dest += width;
00999         oddptr += width;
01000     }
01001 
01002     /* last line may be partial */
01003     if (partial)
01004     {
01005         memcpy(dest, evenptr, width);
01006         dest += width;
01007         oddptr += width;
01008 
01009         memcpy(dest, evenptr, offset);
01010         memset(dest + offset, 0, width - offset);
01011     }
01012     return (0);
01013 }
01014 
01015 
01016 /****************************************
01017 * wrappers 
01018 ****************************************/
01019 pp_deintlv_line_topbottom16(void * p_src, 
01020                   int width, 
01021                   int rows, 
01022                   void * p_dest,
01023                   EdtPostProc *pCtrl)
01024 
01025 {
01026     u_short *src = (u_short *) p_src;
01027     u_short *dest = (u_short *) p_dest;
01028 
01029     return deIntlv_TopBottom16(src, width, rows, dest);
01030 
01031 }
01032 pp_deintlv_line_topbottom8(void * p_src, 
01033                   int width, 
01034                   int rows, 
01035                   void * p_dest,
01036                   EdtPostProc *pCtrl)
01037 
01038 {
01039     u_char *src = (u_char *) p_src;
01040     u_char *dest = (u_char *) p_dest;
01041 
01042     return deIntlv_TopBottom8(src, width, rows, dest);
01043 
01044 }
01045 pp_deintlv_line_inout16(void * p_src, 
01046                   int width, 
01047                   int rows, 
01048                   void * p_dest,
01049                   EdtPostProc *pCtrl)
01050 
01051 {
01052     u_short *src = (u_short *) p_src;
01053     u_short *dest = (u_short *) p_dest;
01054 
01055     return deIntlv_InOut16(src, width, rows, dest);
01056 
01057 }
01058 pp_deintlv_line_inout8(void * p_src, 
01059                   int width, 
01060                   int rows, 
01061                   void * p_dest,
01062                   EdtPostProc *pCtrl)
01063 
01064 {
01065     u_char *src = (u_char *) p_src;
01066     u_char *dest = (u_char *) p_dest;
01067 
01068     return deIntlv_InOut8(src, width, rows, dest);
01069 
01070 }
01071 
01072 int
01073 pp_deintlv_line_taps_8x4(void * p_src, int width, int rows, 
01074                          void * p_dest, EdtPostProc *pCtrl)
01075 
01076 
01077 
01078 {
01079 
01080     u_char *src = (u_char *) p_src;
01081     u_char *dest = (u_char *) p_dest;
01082 
01083     return deintlv_line_taps_8x4(src, width, rows, dest,
01084         pCtrl->nTaps, pCtrl->taps);
01085 
01086 }
01087 
01088 int
01089 pp_deintlv_line_taps_8x4_inv_rt(void *p_src, int width, int rows, void *p_dest,
01090                        EdtPostProc *pCtrl)
01091 
01092 {
01093 
01094     u_char *src = (u_char *) p_src;
01095     u_char *dest = (u_char *) p_dest;
01096 
01097     return deIntlv_line_taps_8x4_inv_rt(src, width, rows, dest);
01098 }
01099 
01100 int
01101 pp_convert_bayer_image_16_BGR(void * p_src, int width, int rows, 
01102                               void * p_dest, EdtPostProc *pCtrl)
01103 
01104 {
01105 
01106     u_short *src = (u_short *) p_src;
01107     u_char *dest = (u_char *) p_dest;
01108 
01109     return convert_bayer_image_16_BGR(src, width, rows,  width, dest,
01110         pCtrl->order, pCtrl->src_depth);
01111 
01112 }
01113 
01114 int
01115 pp_convert_bayer_image_8_BGR(void * p_src, int width, int rows, 
01116                              void * p_dest, EdtPostProc *pCtrl)
01117 
01118 {
01119 
01120     u_char *src = (u_char *) p_src;
01121     u_char *dest = (u_char *) p_dest;
01122 
01123     return convert_bayer_image_8_BGR(src, width, rows,  width, dest,
01124         pCtrl->order);
01125 
01126 }
01127 
01128 int
01129 pp_deIntlv_inv_rt_16_BGR(void * p_src, int width, int rows, 
01130                          void * p_dest, EdtPostProc *pCtrl)
01131 
01132 {
01133 
01134     u_short *src = (u_short *) p_src;
01135     u_char *dest = (u_char *) p_dest;
01136 
01137     return deIntlv_inv_rt_16_BGR(src, width, rows, dest,
01138         pCtrl->order, pCtrl->src_depth);
01139 
01140 }
01141 
01142 int
01143 pp_deIntlv_inv_rt_8_BGR(void * p_src, int width, int rows, 
01144                         void * p_dest, EdtPostProc *pCtrl)
01145 
01146 {
01147 
01148     u_char *src = (u_char *) p_src;
01149     u_char *dest = (u_char *) p_dest;
01150 
01151     return deIntlv_inv_rt_8_BGR(src, width, rows, dest,
01152         pCtrl->order);
01153 
01154 }
01155 int 
01156 pp_deIntlv_quad_16(void *p_src, 
01157                    int width, int rows, 
01158                    void *p_dest,
01159                    EdtPostProc *pCtrl)
01160 
01161 {
01162 
01163     u_short *src = (u_short *) p_src;
01164     u_short *dest = (u_short *) p_dest;
01165 
01166     return deIntlv_quad_16(src, width, rows, dest);
01167 
01168 }
01169 
01170 int
01171 pp_deIntlv_4ch_ill_16(void *p_src, int width, int rows, void * p_dest,
01172                       EdtPostProc *pCtrl)
01173 
01174 {
01175 
01176     u_short *src = (u_short *) p_src;
01177     u_short *dest = (u_short *) p_dest;
01178 
01179     return deIntlv_4ch_ill_16(src, width, rows, dest);
01180 
01181 }
01182 
01183 
01184 int
01185 pp_deIntlv_4ch_ill_8(void *p_src, int width, int rows, void *p_dest,
01186                      EdtPostProc *pCtrl)
01187 
01188 {
01189 
01190     u_char *src = (u_char *) p_src;
01191     u_char *dest = (u_char *) p_dest;
01192 
01193     return deIntlv_4ch_ill_8(src, width, rows, dest);
01194 
01195 }
01196 
01197 
01198 int
01199 pp_deIntlv_piranha_8(void *p_src, int width, int rows, void *p_dest,
01200                      EdtPostProc *pCtrl)
01201 
01202 {
01203 
01204     u_char *src = (u_char *) p_src;
01205     u_char *dest = (u_char *) p_dest;
01206 
01207     return deIntlv_piranha_8(src, width, rows, dest);
01208 
01209 }
01210 
01211 int
01212 pp_deIntlv_dalsa_4ch_8(void *p_src, int width, int rows, void *p_dest,
01213                        EdtPostProc *pCtrl)
01214 
01215 {
01216 
01217     u_char *src = (u_char *) p_src;
01218     u_char *dest = (u_char *) p_dest;
01219 
01220     return deIntlv_dalsa_4ch_8(src, width, rows, dest);
01221 
01222 }
01223 
01224 
01225 int
01226 pp_deIntlv_inv_rt_16(void * p_src, int width, int rows, void * p_dest,
01227                      EdtPostProc *pCtrl)
01228 
01229 {
01230 
01231     u_short *src = (u_short *) p_src;
01232     u_short *dest = (u_short *) p_dest;
01233 
01234     return deIntlv_inv_rt_16(src, width, rows, dest);
01235 
01236 }
01237 
01238 
01239 int
01240 pp_deIntlv_inv_rt_8(void * p_src, int width, int rows, void * p_dest,
01241                     EdtPostProc *pCtrl)
01242 
01243 {
01244 
01245     u_char *src = (u_char *) p_src;
01246     u_char *dest = (u_char *) p_dest;
01247 
01248     return deIntlv_inv_rt_8(src, width, rows, dest);
01249 
01250 }
01251 
01252 
01253 int
01254 pp_deIntlv_2ch_even_rt_16(void * p_src, int width, int rows, void * p_dest,
01255                           EdtPostProc *pCtrl)
01256 
01257 {
01258 
01259     u_short *src = (u_short *) p_src;
01260     u_short *dest = (u_short *) p_dest;
01261 
01262     return deIntlv_2ch_even_rt_16(src, width, rows, dest);
01263 
01264 }
01265 
01266 
01267 int
01268 pp_deIntlv_2ch_even_rt_8(void * p_src, int width, int rows, void * p_dest,
01269                          EdtPostProc *pCtrl)
01270 
01271 {
01272 
01273     u_char *src = (u_char *) p_src;
01274     u_char *dest = (u_char *) p_dest;
01275 
01276     return deIntlv_2ch_even_rt_8(src, width, rows, dest);
01277 
01278 }
01279 
01280 
01281 int 
01282 pp_deIntlv_2ch_inv_rt_24_12(void * p_src, int width, int rows, 
01283                             void * p_dest,
01284                             EdtPostProc *pCtrl)
01285 
01286 {
01287 
01288     u_char *src = (u_char *) p_src;
01289     u_short *dest = (u_short *) p_dest;
01290 
01291     return deIntlv_2ch_inv_rt_24_12(src, width, rows, dest);
01292 
01293 }
01294 
01295 
01296 int 
01297 pp_deIntlv_2ch_24_12(void * p_src, int width, int rows, void * p_dest,
01298                      EdtPostProc *pCtrl)
01299 
01300 {
01301 
01302     u_char *src = (u_char *) p_src;
01303     u_short *dest = (u_short *) p_dest;
01304 
01305     return deIntlv_2ch_24_12(src, width, rows, dest);
01306 
01307 }
01308 
01309 
01310 int
01311 pp_deIntlv_1_8_msb7(void * p_src, 
01312                     int width, 
01313                     int rows, 
01314                     void * p_dest,
01315                     EdtPostProc *pCtrl)
01316 
01317 {
01318 
01319     u_char *src = (u_char *) p_src;
01320     u_char *dest = (u_char *) p_dest;
01321 
01322     return deIntlv_1_8_msb7(src, width, rows, dest);
01323 
01324 }
01325 
01326 int
01327 pp_deIntlv_1_8_msb0(void * p_src, 
01328                     int width, 
01329                     int rows, 
01330                     void * p_dest,
01331                     EdtPostProc *pCtrl)
01332 
01333 {
01334 
01335     u_char *src = (u_char *) p_src;
01336     u_char *dest = (u_char *) p_dest;
01337 
01338     return deIntlv_1_8_msb0(src, width, rows, dest);
01339 
01340 }
01341 
01342 
01343 int
01344 pp_deIntlv_ES10_8(void * p_src, 
01345                   int width, 
01346                   int rows, 
01347                   void * p_dest,
01348                   EdtPostProc *pCtrl)
01349 
01350 {
01351     u_char *src = (u_char *) p_src;
01352     u_char *dest = (u_char *) p_dest;
01353 
01354     return deIntlv_ES10_8(src, width, rows, dest);
01355 
01356 }
01357 
01358 int
01359 pp_ES10deIntlv_16(void * p_src, 
01360                   int width, 
01361                   int rows, 
01362                   void * p_dest,
01363                   EdtPostProc *pCtrl)
01364 
01365 {
01366     u_short *src = (u_short *) p_src;
01367     u_short *dest = (u_short *) p_dest;
01368 
01369     return deIntlv_ES10_16(src, width, rows, dest);
01370 
01371 }
01372 
01373 int
01374 pp_ES10deIntlv_16_odd(void * p_src, 
01375                       int width, 
01376                       int rows, 
01377                       void * p_dest,
01378                       EdtPostProc *pCtrl)
01379 
01380 {
01381     u_short *src = (u_short *) p_src;
01382     u_short *dest = (u_short *) p_dest;
01383 
01384     return deIntlv_ES10_16_odd(src, width, rows, dest);
01385 
01386 }
01387 
01388 int
01389 pp_ES10deIntlv_16_hilo(void * p_src, 
01390                        int width, 
01391                        int rows, 
01392                        void * p_dest,
01393                        EdtPostProc *pCtrl)
01394 
01395 {
01396     u_short *src = (u_short *) p_src;
01397     u_short *dest = (u_short *) p_dest;
01398 
01399     return deIntlv_ES10_16_hilo(src, width, rows, dest);
01400 
01401 }
01402 
01403 int
01404 pp_deIntlv_ES10_8_BGGR(void * p_src, 
01405                        int width, 
01406                        int rows, 
01407                        void * p_dest,
01408                        EdtPostProc *pCtrl)
01409 
01410 {
01411     u_char *src = (u_char *) p_src;
01412     u_char *dest = (u_char *) p_dest;
01413 
01414     /* work in place */
01415 
01416     deIntlv_ES10_8(src, width, rows, src);
01417 
01418     return convert_bayer_image_8_BGR(src, width, rows, width,  dest,
01419         pCtrl->order);  
01420 }
01421 
01422 int 
01423 pp_deIntlv_specinst_4ch_16(void * p_src, 
01424                            int width, 
01425                            int rows, 
01426                            void * p_dest,
01427                            EdtPostProc *pCtrl)
01428 
01429 {
01430     u_short *src = (u_short *) p_src;
01431     u_short *dest = (u_short *) p_dest;
01432 
01433     return deIntlv_specinst_4ch_16(src, width, rows, dest);
01434 
01435 }
01436 
01437 int
01438 pp_merge_fields(void * p_src, 
01439                 int width, 
01440                 int rows, 
01441                 void * p_dest,
01442                 EdtPostProc *pCtrl)
01443 
01444 {
01445     u_char *src = (u_char *) p_src;
01446     u_char *dest = (u_char *) p_dest;
01447 
01448     return deIntlv_merge_fields(src, src + pCtrl->interlace, width, rows, pCtrl->src_depth, dest,
01449         pCtrl->offset);
01450 
01451 }
01452 
01453 int
01454 pp_bgr_2_rgb(void *p_src, 
01455              int width, 
01456              int rows, 
01457              void * p_dest,
01458              EdtPostProc *pCtrl)
01459 
01460 {
01461     u_char *src = (u_char *) p_src;
01462     u_char *dest = (u_char *) p_dest;
01463     int x, y;
01464     int w = width * 3;
01465 
01466     for (y=0;y<rows;y++)
01467     {
01468         for (x = 0; x < w; x+=3)
01469         {
01470             u_char t = src[x];
01471             dest[x] = src[x+2];
01472             dest[x+2] = t;
01473         }
01474         src += w;
01475         dest += w;
01476     }
01477 
01478     return 0;
01479 }
01480 
01481 
01482 int 
01483 pdv_deinterlace(PdvDev *pdv_p, 
01484                 PdvDependent *dd_p, 
01485                 u_char *dmabuf, 
01486                 u_char *output_buf)
01487 
01488 {
01489 
01490     EdtPostProc *pCtrl = NULL;
01491 
01492 
01493     int frame_height = dd_p->height;
01494 
01495     if (pdv_p)
01496         pCtrl = (EdtPostProc *) pdv_p->pInterleaver;
01497 
01498     if (pCtrl == NULL)
01499     {
01500         if (dd_p->swinterlace)
01501             pCtrl = pdv_setup_postproc(pdv_p, dd_p, NULL);
01502 
01503         if (pCtrl == NULL)
01504             return 0;
01505     }
01506 
01507 
01508     if (dd_p->frame_height != 0)
01509     {
01510         frame_height = dd_p->frame_height;
01511     }
01512 
01513     if (pCtrl->process)
01514     {
01515         return pCtrl->process(dmabuf, dd_p->width, frame_height, output_buf, pCtrl);
01516     }
01517     else
01518     {
01519         return -1;
01520     }
01521 
01522 }
01523 
01524 int
01525 deIntlv_buffers(EdtPostProc *pCtrl, void *src_p, void *dest_p, int width, int height)
01526 
01527 {
01528 
01529     if (pCtrl->process)
01530     {
01531         return pCtrl->process(src_p, width, height, dest_p, pCtrl);
01532     }
01533     else
01534     {
01535         return -1;
01536     }   
01537 
01538 }
01539 
01540 
01541 /* Set of default de-interleave functions */
01542 
01543 static EdtPostProc built_in_postproc[] = {
01544     {PDV_BYTE_INTLV, TYPE_BYTE, TYPE_BYTE,
01545         pp_deIntlv_ES10_8, 0},          
01546     {PDV_ES10_BGGR, TYPE_BYTE, TYPE_BGR,
01547     pp_deIntlv_ES10_8_BGGR, 0}, 
01548     {PDV_WORD_INTLV, TYPE_USHORT, TYPE_USHORT,
01549     pp_ES10deIntlv_16, 0},              
01550     {PDV_WORD_INTLV_ODD, TYPE_USHORT, TYPE_USHORT,
01551     pp_ES10deIntlv_16_odd, 0},          
01552     {PDV_WORD_INTLV_HILO, TYPE_USHORT, TYPE_USHORT,
01553     pp_ES10deIntlv_16_hilo, 0},                 
01554     {PDV_FIELD_INTLC, TYPE_BYTE, TYPE_BYTE,
01555     pp_merge_fields, 0},    
01556     {PDV_FIELD_INTLC, TYPE_USHORT, TYPE_USHORT,
01557     pp_merge_fields, 0},                
01558         {PDV_FIELD_INTLC, TYPE_BGR, TYPE_BGR,
01559                 pp_merge_fields, 0},            
01560     {PDV_BGGR_WORD, TYPE_USHORT, TYPE_BGR,
01561     pp_convert_bayer_image_16_BGR, 0}, 
01562     {PDV_BGGR, TYPE_BYTE, TYPE_BGR,
01563     pp_convert_bayer_image_8_BGR, 0}, 
01564     {PDV_DALSA_4CH_INTLV, TYPE_BYTE, TYPE_BYTE,
01565     pp_deIntlv_dalsa_4ch_8, 0},                 
01566     {PDV_INVERT_RIGHT_INTLV, TYPE_BYTE, TYPE_BYTE, 
01567     pp_deIntlv_inv_rt_8, 0}, 
01568     {PDV_INVERT_RIGHT_INTLV, TYPE_USHORT, TYPE_USHORT, 
01569     pp_deIntlv_inv_rt_16, 0}, 
01570     {PDV_INVERT_RIGHT_BGGR_INTLV, TYPE_BYTE, TYPE_BGR, 
01571     pp_deIntlv_inv_rt_8_BGR, 0}, 
01572     {PDV_INVERT_RIGHT_BGGR_INTLV, TYPE_USHORT, TYPE_BGR, 
01573     pp_deIntlv_inv_rt_16_BGR, 0}, 
01574     {PDV_EVEN_RIGHT_INTLV, TYPE_BYTE, TYPE_BYTE,
01575     pp_deIntlv_2ch_even_rt_8, 0}, 
01576     {PDV_EVEN_RIGHT_INTLV, TYPE_USHORT, TYPE_USHORT,
01577     pp_deIntlv_2ch_even_rt_16, 0},              
01578     {PDV_PIRANHA_4CH_INTLV, TYPE_BYTE, TYPE_BYTE,
01579     pp_deIntlv_piranha_8, 0}, 
01580     {PDV_PIRANHA_4CH_INTLV, TYPE_USHORT, TYPE_BYTE,
01581     pp_deIntlv_piranha_8, 0}, 
01582     {PDV_SPECINST_4PORT_INTLV, TYPE_USHORT, TYPE_USHORT,
01583     pp_deIntlv_specinst_4ch_16, 0}, 
01584     {PDV_QUADRANT_INTLV, TYPE_USHORT, TYPE_USHORT,
01585     pp_deIntlv_quad_16, 0}, 
01586     {PDV_ILLUNIS_INTLV, TYPE_BYTE, TYPE_BYTE,
01587     pp_deIntlv_4ch_ill_8, 0}, 
01588     {PDV_ILLUNIS_INTLV, TYPE_SHORT, TYPE_USHORT,
01589     pp_deIntlv_4ch_ill_16, 0}, 
01590     {PDV_INV_RT_INTLV_24_12, TYPE_BGR, TYPE_USHORT,
01591     pp_deIntlv_2ch_inv_rt_24_12, 0}, 
01592     {PDV_INTLV_24_12, TYPE_BGR, TYPE_USHORT,
01593     pp_deIntlv_2ch_24_12, 0}, 
01594     {PDV_INTLV_1_8_MSB7, TYPE_BYTE, TYPE_BYTE,
01595     pp_deIntlv_1_8_msb7, 0}, 
01596     {PDV_INTLV_1_8_MSB0, TYPE_BYTE, TYPE_BYTE,
01597     pp_deIntlv_1_8_msb0},
01598     {PDV_INTLV_BGR_2_RGB, TYPE_BGR, TYPE_BGR, /* use TYPE_BGR since display expects it */
01599     pp_bgr_2_rgb},
01600     {PDV_LINE_INTLV, TYPE_BYTE, TYPE_BYTE, 
01601     pp_deintlv_line_taps_8x4},
01602     {PDV_LINE_INTLV_P3_8X4, TYPE_BYTE, TYPE_BYTE, 
01603     pp_deintlv_line_taps_8x4_inv_rt},
01604     {PDV_WORD_INTLV_TOPBOTTOM, TYPE_USHORT, TYPE_USHORT, 
01605     pp_deintlv_line_topbottom16},
01606     {PDV_BYTE_INTLV_TOPBOTTOM, TYPE_BYTE, TYPE_BYTE, 
01607     pp_deintlv_line_topbottom8},
01608     {PDV_WORD_INTLV_INOUT, TYPE_USHORT, TYPE_USHORT, 
01609     pp_deintlv_line_inout16},
01610     {PDV_BYTE_INTLV_INOUT, TYPE_BYTE, TYPE_BYTE, 
01611     pp_deintlv_line_inout8},
01612     {0,0,0,0}
01613 };
01614 
01615 /* default pixel types from depth */
01616 
01617 int pdv_pixel_type_from_depth(int depth)
01618 {
01619 
01620     int type = TYPE_BYTE;
01621     if (depth <= 8)
01622         type =  TYPE_BYTE;
01623     else if (depth >8 && depth <= 16)
01624         type =  TYPE_USHORT;
01625     else if (depth > 16 && depth <= 24)
01626         type =  TYPE_BGR;
01627     else
01628         type =  TYPE_BGRA;
01629 
01630     return type;
01631 }       
01632 
01633 
01634 EdtPostProc *
01635 pdv_lookup_postproc(int func_type, int src_depth, int depth)
01636 
01637 {
01638     EdtPostProc *pCtrl;
01639 
01640     int src_type = pdv_pixel_type_from_depth(src_depth);
01641     int dest_type = pdv_pixel_type_from_depth(depth);
01642 
01643     pCtrl = &built_in_postproc[0];
01644 
01645     while (pCtrl->func_type != 0 &&
01646         (pCtrl->func_type != func_type ||
01647         pCtrl->src_type != src_type ||
01648         pCtrl->dest_type != dest_type))
01649     {
01650         pCtrl ++;
01651     }
01652 
01653     if (pCtrl->func_type == 0)
01654 
01655         return NULL;
01656 
01657     return pCtrl;
01658 
01659 }
01660 
01661 
01662 int 
01663 pdv_set_postproc(EdtPostProc *pCtrl,
01664                  int depth,
01665                  int extdepth,
01666                  int frame_height,
01667                  int interlace,
01668                  int image_offset,
01669                  int order,
01670                  int n_intlv_taps,
01671                  PdvInterleaveTap *taps
01672                  )
01673 
01674 {
01675 
01676 
01677     pCtrl->interlace = interlace;
01678     pCtrl->order = order;
01679 
01680     pCtrl->frame_height = frame_height;
01681 
01682     pCtrl->src_type = pdv_pixel_type_from_depth(extdepth);
01683     pCtrl->dest_type = pdv_pixel_type_from_depth(depth);
01684 
01685     pCtrl->src_depth = extdepth;
01686     pCtrl->dest_depth = depth;
01687 
01688     pCtrl->offset = image_offset;
01689 
01690     pCtrl->nTaps = n_intlv_taps;
01691     if (n_intlv_taps)
01692         memcpy(pCtrl->taps, taps, n_intlv_taps * sizeof(PdvInterleaveTap));
01693 
01694     return 0;
01695 
01696 
01697 }
01698 
01699 int 
01700 pdv_update_postproc(PdvDev *pdv_p, PdvDependent *dd_p,  EdtPostProc *pCtrl)
01701 
01702 {
01703     /* fill in the width, height, depth, etc. */
01704 
01705     if (dd_p == NULL)
01706     {
01707         if (pdv_p)
01708             dd_p = pdv_p->dd_p;
01709         else
01710             return -1;
01711     }
01712 
01713     pdv_set_postproc(pCtrl,
01714         dd_p->depth,
01715         dd_p->extdepth,
01716         dd_p->frame_height,
01717         dd_p->interlace,
01718         dd_p->image_offset,
01719         PDV_BAYER_ORDER(dd_p),
01720         dd_p->n_intlv_taps,
01721         dd_p->intlv_taps);
01722 
01723 
01724 
01725     return 0;
01726 
01727 
01728 }
01729 
01730 
01731 EdtPostProc *
01732 pdv_setup_postproc(PdvDev *pdv_p, PdvDependent *dd_p, EdtPostProc *pInCtrl)
01733 
01734 {
01735 
01736     EdtPostProc *pCtrl = pInCtrl;
01737 
01738     /* look up swinterlace */
01739     if (dd_p == NULL)
01740         dd_p = pdv_p->dd_p;
01741 
01742     if (dd_p->interlace_module[0])
01743     {
01744         if (!pInCtrl)
01745         {
01746             pCtrl = (EdtPostProc *) edt_alloc(sizeof(*pInCtrl));
01747 
01748             memset(pCtrl,0,sizeof(*pCtrl));
01749 
01750             if (pdv_load_postproc_module(pCtrl, dd_p->interlace_module,
01751                 dd_p->extdepth, dd_p->depth) == 0)
01752             {
01753 
01754 
01755                 if (pdv_p)
01756                     pdv_p->pInterleaver = pCtrl;
01757 
01758                 pdv_update_postproc(pdv_p, dd_p, pCtrl);        
01759 
01760                 if (pCtrl->defaultInit)
01761                     pCtrl->defaultInit(pdv_p, pCtrl);
01762 
01763                 return pCtrl;
01764             }
01765 
01766         }
01767 
01768 
01769     }
01770 
01771     if (dd_p->swinterlace)
01772     {
01773 
01774         if (pInCtrl == NULL)
01775             pInCtrl = pdv_lookup_postproc(dd_p->swinterlace, 
01776             dd_p->extdepth, dd_p->depth);
01777 
01778     }
01779 
01780     /* update  */
01781 
01782 
01783     if (pInCtrl)
01784     {
01785 
01786         pCtrl = (EdtPostProc *) edt_alloc(sizeof(*pCtrl));
01787 
01788         memcpy(pCtrl, pInCtrl, sizeof(*pCtrl));
01789 
01790         if (pdv_p)
01791             pdv_p->pInterleaver = pCtrl;
01792 
01793         pdv_update_postproc(pdv_p, dd_p, pCtrl);        
01794 
01795         if (pCtrl->defaultInit)
01796             pCtrl->defaultInit(pdv_p, pCtrl);
01797 
01798     }
01799 
01800     return pCtrl;
01801 }
01802 
01803 int
01804 pdv_unload_postproc_module(EdtPostProc *pCtrl)
01805 
01806 {
01807     return 0;
01808 }
01809 
01810 int
01811 pdv_load_postproc_module(EdtPostProc *pCtrl,
01812                          char *name,
01813                          int srcdepth,
01814                          int destdepth)
01815 
01816 {
01817 
01818 #ifdef WIN32
01819     char process_name[80];
01820     char filename[MAX_PATH];
01821 
01822 
01823     pCtrl->dll_handle = LoadLibrary(name);
01824 
01825     if (!pCtrl->dll_handle)
01826     {
01827         sprintf(filename,"postproc/%s", name);
01828         pCtrl->dll_handle = LoadLibrary(filename);
01829     }
01830 
01831     if (pCtrl->dll_handle)
01832     {
01833         strcpy(pCtrl->dll_name, name);
01834 
01835         if (srcdepth > 8 && srcdepth < 16)
01836             srcdepth = 16;
01837 
01838         if (destdepth > 8 && destdepth < 16)
01839             destdepth = 16;
01840 
01841         sprintf(process_name, "post_process_%d_%d", srcdepth, destdepth);
01842 
01843         pCtrl->process = (post_process_f) GetProcAddress(pCtrl->dll_handle,
01844             process_name);
01845 
01846         pCtrl->doinplace = (int (*)()) GetProcAddress(pCtrl->dll_handle,
01847             "post_process_doinplace");
01848 
01849     }
01850     else
01851     {
01852         return -1;
01853 
01854     }
01855 
01856 #elif defined(__linux__)
01857 
01858 #include <dlfcn.h>
01859 
01860     char process_name[80];
01861 
01862     pCtrl->dll_handle = dlopen(name, RTLD_LAZY);
01863 
01864     if (pCtrl->dll_handle)
01865     {
01866         strcpy(pCtrl->dll_name, name);
01867 
01868         if (srcdepth > 8 && srcdepth < 16)
01869             srcdepth = 16;
01870 
01871         if (destdepth > 8 && destdepth < 16)
01872             destdepth = 16;
01873 
01874         sprintf(process_name, "post_process_%d_%d", srcdepth, destdepth);
01875 
01876         pCtrl->process = (post_process_f) dlsym(pCtrl->dll_handle,
01877             process_name);
01878 
01879         pCtrl->doinplace = (int (*)()) dlsym(pCtrl->dll_handle,
01880             "post_process_doinplace");
01881 
01882     }
01883     else
01884     {
01885         return -1;
01886 
01887     }
01888 
01889 
01890 #endif
01891 
01892     return 0;
01893 
01894 }
01895 

Generated on Mon Mar 21 14:14:53 2011 by  doxygen 1.4.7