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