00001
00007 #include "edtinc.h"
00008
00009 #include "pdv_interlace_methods.h"
00010
00011
00012
00013
00014
00015 #ifdef USE_MMX
00016
00017 #include "bayer_filter_asm.h"
00018
00019 #endif
00020
00021
00022 #include <math.h>
00023
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
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
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
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
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
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
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++);
00261 *(dxr) = *(sx++);
00262 dxr -= 2;
00263 }
00264 }
00265 return (0);
00266 }
00267
00268
00269
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
00298
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
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
00623
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
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
00661
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
00703
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
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
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
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
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
00819 if (rows & 1)
00820 rows--;
00821
00822
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
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
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
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
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
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,
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
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
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
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
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->