/* WARNING, this function is not endian safe! */ static void blit_8i_to_32_ab(__u32 *dst, __u8 *src, __u32 *pal, int width) { while (width--) { #define BLEND(x, y, a) (y + (((x-y) * a)>>8)) __u32 srccol = pal[*src++]; __u32 dstcol = *dst; unsigned char sb = srccol & 0xFF; unsigned char sg = (srccol >> 8) & 0xFF; unsigned char sr = (srccol >> 16) & 0xFF; unsigned char sa = (srccol >> 24) & 0xFF; unsigned char db = dstcol & 0xFF; unsigned char dg = (dstcol >> 8) & 0xFF; unsigned char dr = (dstcol >> 16) & 0xFF; unsigned char da = (dstcol >> 24) & 0xFF; da = BLEND(0xFF, da, sa) & 0xFF; dr = BLEND(sr, dr, sa) & 0xFF; dg = BLEND(sg, dg, sa) & 0xFF; db = BLEND(sb, db, sa) & 0xFF; #undef BLEND *dst++ = db | (dg << 8) | (dr << 16) | (da << 24); } }
static void tegra_dc_blend_parallel(struct tegra_dc *dc, struct tegra_dc_blend *blend) { int win_num = dc->gen1_blend_num; unsigned long mask = BIT(win_num) - 1; tegra_dc_io_start(dc); while (mask) { int idx = get_topmost_window(blend->z, &mask, win_num); tegra_dc_writel(dc, WINDOW_A_SELECT << idx, DC_CMD_DISPLAY_WINDOW_HEADER); tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff), DC_WIN_BLEND_NOKEY); tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff), DC_WIN_BLEND_1WIN); tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 0, win_num), DC_WIN_BLEND_2WIN_X); tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 1, win_num), DC_WIN_BLEND_2WIN_Y); tegra_dc_writel(dc, blend_3win(idx, mask, blend->flags, win_num), DC_WIN_BLEND_3WIN_XY); } tegra_dc_io_end(dc); }
static inline void T_mdp_render_interpolated_scanline_50_cpp(pixel *destScreen, pixel *mdScreen, int destPitch, int srcPitch, int width, int height, pixel mask) { destPitch /= sizeof(pixel); srcPitch /= sizeof(pixel); // TODO: Figure out why the interpolation function is using the line // below the source line instead of using the current source line. for (int y = 0; y < height; y++) { pixel *SrcLine = &mdScreen[y * srcPitch]; pixel *DstLine1 = &destScreen[(y * 2) * destPitch]; pixel *DstLine2 = &destScreen[((y * 2) + 1) * destPitch]; for (int x = 0; x < width; x++) { pixel C = *(SrcLine); pixel R = *(SrcLine + 1); pixel D = *(SrcLine + srcPitch); pixel DR = *(SrcLine + srcPitch + 1); *DstLine1++ = C; *DstLine1++ = BLEND(C, R, mask); *DstLine2++ = (BLEND(C, D, mask) >> 1) & mask; *DstLine2++ = ((BLEND(BLEND(C, R, mask), BLEND(D, DR, mask), mask)) >> 1) & mask; SrcLine++; } } }
static inline void hline32rgba(Imaging im, int x0, int y0, int x1, int ink) { int tmp; unsigned int tmp1, tmp2; if (y0 >= 0 && y0 < im->ysize) { if (x0 > x1) tmp = x0, x0 = x1, x1 = tmp; if (x0 < 0) x0 = 0; else if (x0 >= im->xsize) return; if (x1 < 0) return; else if (x1 >= im->xsize) x1 = im->xsize-1; if (x0 <= x1) { UINT8* out = (UINT8*) im->image[y0]+x0*4; UINT8* in = (UINT8*) &ink; while (x0 <= x1) { out[0] = BLEND(in[3], out[0], in[0], tmp1, tmp2); out[1] = BLEND(in[3], out[1], in[1], tmp1, tmp2); out[2] = BLEND(in[3], out[2], in[2], tmp1, tmp2); x0++; out += 4; } } } }
static u32 blend_topwin(u32 flags) { if (flags & TEGRA_WIN_FLAG_BLEND_COVERAGE) return BLEND(NOKEY, ALPHA, 0xff, 0xff); else if (flags & TEGRA_WIN_FLAG_BLEND_PREMULT) return BLEND(NOKEY, PREMULT, 0xff, 0xff); else return BLEND(NOKEY, FIX, 0xff, 0xff); }
static inline void point32rgba(Imaging im, int x, int y, int ink) { unsigned int tmp1, tmp2; if (x >= 0 && x < im->xsize && y >= 0 && y < im->ysize) { UINT8* out = (UINT8*) im->image[y]+x*4; UINT8* in = (UINT8*) &ink; out[0] = BLEND(in[3], out[0], in[0], tmp1, tmp2); out[1] = BLEND(in[3], out[1], in[1], tmp1, tmp2); out[2] = BLEND(in[3], out[2], in[2], tmp1, tmp2); } }
static u32 blend_2win(int idx, unsigned long behind_mask, u32* flags, int xy) { int other; for (other = 0; other < DC_N_WINDOWS; other++) { if (other != idx && (xy-- == 0)) break; } if (BIT(other) & behind_mask) return blend_topwin(flags[idx]); else if (flags[other]) return BLEND(NOKEY, DEPENDANT, 0x00, 0x00); else return BLEND(NOKEY, FIX, 0x00, 0x00); }
static u32 blend_3win(int idx, unsigned long behind_mask, u32* flags) { unsigned long infront_mask; int first; infront_mask = ~(behind_mask | BIT(idx)); infront_mask &= (BIT(DC_N_WINDOWS) - 1); first = ffs(infront_mask) - 1; if (!infront_mask) return blend_topwin(flags[idx]); else if (behind_mask && first != -1 && flags[first]) return BLEND(NOKEY, DEPENDANT, 0x00, 0x00); else return BLEND(NOKEY, FIX, 0x0, 0x0); }
void CVisualizerSpectrum::Draw() { ASSERT(m_pFftObject != NULL); static const float SCALING = 250.0f; static const int OFFSET = 0; static const float DECAY = 3.0f; float Step = 0.2f * (float(FFT_POINTS) / float(m_iWidth)) * m_iBarSize; // // // float Pos = 2; // Add a small offset to remove note on/off actions int LastStep = 0; for (int i = 0; i < m_iWidth / m_iBarSize; i++) { // // // int iStep = int(Pos + 0.5f); float level = 0; int steps = (iStep - LastStep) + 1; for (int j = 0; j < steps; ++j) level += float(m_pFftObject->GetIntensity(LastStep + j)) / SCALING; level /= steps; // linear -> db level = (20 * logf(level / 4.0f)) * 0.8f; if (level < 0.0f) level = 0.0f; if (level > float(m_iHeight)) level = float(m_iHeight); if (iStep != LastStep) { if (level >= m_fFftPoint[iStep]) m_fFftPoint[iStep] = level; else m_fFftPoint[iStep] -= DECAY; if (m_fFftPoint[iStep] < 1.0f) m_fFftPoint[iStep] = 0.0f; } level = m_fFftPoint[iStep]; for (int y = 0; y < m_iHeight; ++y) { COLORREF Color = BLEND(0x6060FF, 0xFFFFFF, (y * 100) / int(level + 1)); if (y == 0) Color = DIM(Color, 90); if (m_iBarSize > 1 && (y & 1)) // // // Color = DIM(Color, 40); for (int x = 0; x < m_iBarSize; ++x) { // // // if (m_iBarSize > 1 && x == m_iBarSize - 1) Color = DIM(Color, 50); m_pBlitBuffer[(m_iHeight - y - 1) * m_iWidth + i * m_iBarSize + x + OFFSET] = y < level ? Color : BG_COLOR; } } LastStep = iStep; Pos += Step; } }
static void tegra_dc_set_blending(struct tegra_dc *dc, struct tegra_dc_blend *blend) { unsigned long mask = BIT(DC_N_WINDOWS) - 1; while (mask) { int idx = get_topmost_window(blend->z, &mask); tegra_dc_writel(dc, WINDOW_A_SELECT << idx, DC_CMD_DISPLAY_WINDOW_HEADER); tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff), DC_WIN_BLEND_NOKEY); tegra_dc_writel(dc, BLEND(NOKEY, FIX, 0xff, 0xff), DC_WIN_BLEND_1WIN); tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 0), DC_WIN_BLEND_2WIN_X); tegra_dc_writel(dc, blend_2win(idx, mask, blend->flags, 1), DC_WIN_BLEND_2WIN_Y); tegra_dc_writel(dc, blend_3win(idx, mask, blend->flags), DC_WIN_BLEND_3WIN_XY); } }
static inline void paste_mask_L(Imaging imOut, Imaging imIn, Imaging imMask, int dx, int dy, int sx, int sy, int xsize, int ysize, int pixelsize) { /* paste with mode "L" matte */ int x, y; unsigned int tmp1; if (imOut->image8) { for (y = 0; y < ysize; y++) { UINT8* out = imOut->image8[y+dy]+dx; UINT8* in = imIn->image8[y+sy]+sx; UINT8* mask = imMask->image8[y+sy]+sx; for (x = 0; x < xsize; x++) { *out = BLEND(*mask, *out, *in, tmp1); out++, in++, mask++; } } } else { for (y = 0; y < ysize; y++) { UINT8* out = (UINT8*) (imOut->image32[y + dy] + dx); UINT8* in = (UINT8*) (imIn->image32[y + sy] + sx); UINT8* mask = (UINT8*) (imMask->image8[y+sy] + sx); for (x = 0; x < xsize; x++) { UINT8 a = mask[0]; out[0] = BLEND(a, out[0], in[0], tmp1); out[1] = BLEND(a, out[1], in[1], tmp1); out[2] = BLEND(a, out[2], in[2], tmp1); out[3] = BLEND(a, out[3], in[3], tmp1); out += 4; in += 4; mask ++; } } } }
static inline void fill_mask_RGBA(Imaging imOut, const UINT8* ink, Imaging imMask, int dx, int dy, int sx, int sy, int xsize, int ysize, int pixelsize) { /* fill with mode "RGBA" matte */ int x, y, i; unsigned int tmp1, tmp2; if (imOut->image8) { sx = sx*4+3; for (y = 0; y < ysize; y++) { UINT8* out = imOut->image8[y+dy]+dx; UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; for (x = 0; x < xsize; x++) { *out = BLEND(*mask, *out, ink[0], tmp1, tmp2); out++, mask += 4; } } } else { dx *= pixelsize; sx = sx*4 + 3; for (y = 0; y < ysize; y++) { UINT8* out = (UINT8*) imOut->image[y+dy]+dx; UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; for (x = 0; x < xsize; x++) { for (i = 0; i < pixelsize; i++) { *out = BLEND(*mask, *out, ink[i], tmp1, tmp2); out++; } mask += 4; } } } }
static inline void paste_mask_L(Imaging imOut, Imaging imIn, Imaging imMask, int dx, int dy, int sx, int sy, int xsize, int ysize, int pixelsize) { /* paste with mode "L" matte */ int x, y, i; unsigned int tmp1, tmp2; if (imOut->image8) { for (y = 0; y < ysize; y++) { UINT8* out = imOut->image8[y+dy]+dx; UINT8* in = imIn->image8[y+sy]+sx; UINT8* mask = imMask->image8[y+sy]+sx; for (x = 0; x < xsize; x++) { *out = BLEND(*mask, *out, *in, tmp1, tmp2); out++, in++, mask++; } } } else { for (y = 0; y < ysize; y++) { UINT8* out = (UINT8*) imOut->image[y+dy]+dx*pixelsize; UINT8* in = (UINT8*) imIn->image[y+sy]+sx*pixelsize; UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; for (x = 0; x < xsize; x++) { for (i = 0; i < pixelsize; i++) { *out = BLEND(*mask, *out, *in, tmp1, tmp2); out++, in++; } mask++; } } } }
BLEND BlendFromString(const char* str) { if (!str) return BLEND_ONE; for (int i = 1; i <= 19; i++) { if (_stricmp(str, STR_BLEND[i - 1]) == 0) { return BLEND(i); } } Logger::Log(FB_ERROR_LOG_ARG, FormatString("%s is not valid Blend.", str).c_str()); return BLEND_ONE; }
void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb) { const int red = (background_rgb >> 16) & 0xff; const int green = (background_rgb >> 8) & 0xff; const int blue = (background_rgb >> 0) & 0xff; int x, y; if (pic == NULL) return; if (!pic->use_argb) { const int uv_width = (pic->width >> 1); // omit last pixel during u/v loop const int Y0 = VP8RGBToY(red, green, blue, YUV_HALF); // VP8RGBToU/V expects the u/v values summed over four pixels const int U0 = VP8RGBToU(4 * red, 4 * green, 4 * blue, 4 * YUV_HALF); const int V0 = VP8RGBToV(4 * red, 4 * green, 4 * blue, 4 * YUV_HALF); const int has_alpha = pic->colorspace & WEBP_CSP_ALPHA_BIT; if (!has_alpha || pic->a == NULL) return; // nothing to do for (y = 0; y < pic->height; ++y) { // Luma blending uint8_t* const y_ptr = pic->y + y * pic->y_stride; uint8_t* const a_ptr = pic->a + y * pic->a_stride; for (x = 0; x < pic->width; ++x) { const int alpha = a_ptr[x]; if (alpha < 0xff) { y_ptr[x] = BLEND(Y0, y_ptr[x], a_ptr[x]); } } // Chroma blending every even line if ((y & 1) == 0) { uint8_t* const u = pic->u + (y >> 1) * pic->uv_stride; uint8_t* const v = pic->v + (y >> 1) * pic->uv_stride; uint8_t* const a_ptr2 = (y + 1 == pic->height) ? a_ptr : a_ptr + pic->a_stride; for (x = 0; x < uv_width; ++x) { // Average four alpha values into a single blending weight. // TODO(skal): might lead to visible contouring. Can we do better? const int alpha = a_ptr[2 * x + 0] + a_ptr[2 * x + 1] + a_ptr2[2 * x + 0] + a_ptr2[2 * x + 1]; u[x] = BLEND_10BIT(U0, u[x], alpha); v[x] = BLEND_10BIT(V0, v[x], alpha); } if (pic->width & 1) { // rightmost pixel const int alpha = 2 * (a_ptr[2 * x + 0] + a_ptr2[2 * x + 0]); u[x] = BLEND_10BIT(U0, u[x], alpha); v[x] = BLEND_10BIT(V0, v[x], alpha); } } memset(a_ptr, 0xff, pic->width); } } else {
INLINE void bitmap_4_draw(INT32 firstpix, INT32 iwidth, UINT32 *src, INT32 xpos, UINT8 flags, INT32 dxpos) { if (firstpix & 7) { UINT32 pixsrc = src[firstpix / 8]; while (firstpix & 7) { int pix = (pixsrc >> (4 * (~firstpix & 7))) & 0x0f; if ((!(flags & 4) || pix) && (UINT32)xpos < 360) { if (!(flags & 2)) scanline[xpos] = clutbase[BYTE_XOR_BE(pix)]; else BLEND(scanline[xpos], clutbase[BYTE_XOR_BE(pix)]); } xpos += dxpos; firstpix++; } }
inline static void _blend_u8_c (guint8 * dest, const guint8 * src, gint src_stride, gint dest_stride, gint src_width, gint src_height, gint dest_width, gint b_alpha) { gint i, j; gint src_add = src_stride - src_width; gint dest_add = dest_stride - dest_width; for (i = 0; i < src_height; i++) { for (j = 0; j < src_width; j++) { *dest = BLEND (*dest, *src, b_alpha); dest++; src++; } src += src_add; dest += dest_add; } }
inline void jaguar_state::bitmap_4_draw(UINT16 *scanline, INT32 firstpix, INT32 iwidth, UINT32 *src, INT32 xpos, UINT8 flags, INT32 dxpos, UINT16 *clutbase) { if (firstpix & 7) { UINT32 pixsrc = src[firstpix >> 3]; while (firstpix & 7) { int pix = (pixsrc >> ((~firstpix & 7) << 2)) & 0x0f; if ((!(flags & 4) || pix) && (UINT32)xpos < 760) { if (!(flags & 2)) scanline[xpos] = clutbase[BYTE_XOR_BE(pix)]; else BLEND(scanline[xpos], clutbase[BYTE_XOR_BE(pix)]); } xpos += dxpos; firstpix++; } }
void CNoiseEditor::OnPaint() { ASSERT(m_pBackDC != NULL); CPaintDC dc(this); DrawBackground(m_pBackDC, m_iItems, false, 0); DrawRange(m_pBackDC, m_iItems, 0); // Return now if no sequence is selected if (!m_pSequence) { PaintBuffer(m_pBackDC, &dc); return; } // Draw items int Count = m_pSequence->GetItemCount(); if (!Count) { PaintBuffer(m_pBackDC, &dc); return; } int StepWidth = GetItemWidth(); int StepHeight = m_GraphRect.Height() / m_iItems; // Draw items for (int i = 0; i < Count; i++) { // Draw noise frequency int item = m_pSequence->GetItem(i) & 0x1F; int x = m_GraphRect.left + i * StepWidth + 1; int y = m_GraphRect.top + StepHeight * (m_iItems - item); int w = StepWidth; int h = StepHeight;//* item; if (m_iCurrentPlayPos == i) DrawPlayRect(m_pBackDC, x, y, w, h); else DrawRect(m_pBackDC, x, y, w, h); // Draw switches item = m_pSequence->GetItem(i); int Offset = h * 36 - 1; if (item & S5B_MODE_SQUARE) { static const COLORREF BUTTON_COL = COMBINE(0, 160, 160); int y = Offset; int h = 9; m_pBackDC->FillSolidRect(x, y, w, h, BUTTON_COL); m_pBackDC->Draw3dRect(x, y, w, h, BLEND(BUTTON_COL, 0xFFFFFF, 80), BLEND(BUTTON_COL, 0x000000, 80)); } else { static const COLORREF BUTTON_COL = COMBINE(50, 50, 50); int y = Offset; int h = 9; m_pBackDC->FillSolidRect(x, y, w, h, BUTTON_COL); m_pBackDC->Draw3dRect(x, y, w, h, BLEND(BUTTON_COL, 0xFFFFFF, 80), BLEND(BUTTON_COL, 0x000000, 80)); } if (item & S5B_MODE_NOISE) { static const COLORREF BUTTON_COL = COMBINE(160, 0, 160); int y = Offset + 11; int h = 9; m_pBackDC->FillSolidRect(x, y, w, h, BUTTON_COL); m_pBackDC->Draw3dRect(x, y, w, h, BLEND(BUTTON_COL, 0xFFFFFF, 80), BLEND(BUTTON_COL, 0x000000, 80)); } else { static const COLORREF BUTTON_COL = COMBINE(50, 50, 50); int y = Offset + 11; int h = 9; m_pBackDC->FillSolidRect(x, y, w, h, BUTTON_COL); m_pBackDC->Draw3dRect(x, y, w, h, BLEND(BUTTON_COL, 0xFFFFFF, 80), BLEND(BUTTON_COL, 0x000000, 80)); } } DrawLoopPoint(m_pBackDC, StepWidth); DrawReleasePoint(m_pBackDC, StepWidth); DrawLine(m_pBackDC); PaintBuffer(m_pBackDC, &dc); }
int ShapeWipeMain::process_realtime(VFrame *incoming, VFrame *outgoing) { unsigned char *pattern_row; int col_offset; unsigned char threshold; unsigned char value; int i,j,k; int opacity; init_shapes(); load_configuration(); int w = incoming->get_w(); int h = incoming->get_h(); if (strncmp(filename, last_read_filename, BCTEXTLEN) || strncmp(shape_name, current_name, BCTEXTLEN) || preserve_aspect != last_preserve_aspect) { reset_pattern_image(); } if (!pattern_image) { read_pattern_image(w, h); strncpy(last_read_filename, filename, BCTEXTLEN); strncpy(current_name, shape_name, BCTEXTLEN); last_preserve_aspect = preserve_aspect; } if (!pattern_image) { fprintf(stderr, "Shape Wipe: cannot load shape %s\n", filename); return 0; } if (direction) { threshold = (unsigned char)( (float)PluginClient::get_source_position() / (float)PluginClient::get_total_len() * (float)(max_value - min_value)) + min_value; } else { threshold = (unsigned char)((max_value - min_value) - ( (float)PluginClient::get_source_position() / (float)PluginClient::get_total_len() * (float)(max_value - min_value))) + min_value; } if (antialias) { if (direction) { /* Top left corner */ opacity = 0; COMPARE1(0,0); COMPARE1(0,1); COMPARE1(1,0); COMPARE1(1,1); BLEND(0,0,4.0); /* Top edge */ for (k = 1; k < w-1; k++) { opacity = 0; COMPARE1(0,k-1); COMPARE1(0,k); COMPARE1(0,k+1); COMPARE1(1,k-1); COMPARE1(1,k); COMPARE1(1,k+1); BLEND(0,k,6.0); } /* Top right corner */ opacity = 0; COMPARE1(0,w-1); COMPARE1(0,w-2); COMPARE1(1,w-1); COMPARE1(1,w-2); BLEND(0,w-1,4.0); /* Left edge */ for (j = 1; j < h-1; j++) { opacity = 0; COMPARE1(j-1,0); COMPARE1(j,0); COMPARE1(j+1,0); COMPARE1(j-1,1); COMPARE1(j,1); COMPARE1(j+1,1); BLEND(j,0,6.0); } /* Middle */ for (j = 1; j < h-1; j++) { for (k = 1; k < w-1; k++) { opacity = 0; COMPARE1(j-1,k-1); COMPARE1(j,k-1); COMPARE1(j+1,k-1); COMPARE1(j-1,k); COMPARE1(j,k); COMPARE1(j+1,k); COMPARE1(j-1,k+1); COMPARE1(j,k+1); COMPARE1(j+1,k+1); BLEND(j,k,9.0); } } /* Right edge */ for (j = 1; j < h-1; j++) { opacity = 0; COMPARE1(j-1,w-1); COMPARE1(j,w-1); COMPARE1(j+1,w-1); COMPARE1(j-1,w-2); COMPARE1(j,w-2); COMPARE1(j+1,w-2); BLEND(j,w-1,6.0); } /* Bottom left corner */ opacity = 0; COMPARE1(h-1,0); COMPARE1(h-1,1); COMPARE1(h-2,0); COMPARE1(h-2,1); BLEND(h-1,0,4.0); /* Bottom edge */ for (k = 1; k < w-1; k++) { opacity = 0; COMPARE1(h-1,k-1); COMPARE1(h-1,k); COMPARE1(h-1,k+1); COMPARE1(h-2,k-1); COMPARE1(h-2,k); COMPARE1(h-2,k+1); BLEND(h-1,k,6.0); } /* Bottom right corner */ opacity = 0; COMPARE1(h-1,w-1); COMPARE1(h-1,w-2); COMPARE1(h-2,w-1); COMPARE1(h-2,w-2); BLEND(h-1,w-1,4.0); } else { /* Top left corner */ opacity = 0; COMPARE2(0,0); COMPARE2(0,1); COMPARE2(1,0); COMPARE2(1,1); BLEND(0,0,4.0); /* Top edge */ for (k = 1; k < w-1; k++) { opacity = 0; COMPARE2(0,k-1); COMPARE2(0,k); COMPARE2(0,k+1); COMPARE2(1,k-1); COMPARE2(1,k); COMPARE2(1,k+1); BLEND(0,k,6.0); } /* Top right corner */ opacity = 0; COMPARE2(0,w-1); COMPARE2(0,w-2); COMPARE2(1,w-1); COMPARE2(1,w-2); BLEND(0,w-1,4.0); /* Left edge */ for (j = 1; j < h-1; j++) { opacity = 0; COMPARE2(j-1,0); COMPARE2(j,0); COMPARE2(j+1,0); COMPARE2(j-1,1); COMPARE2(j,1); COMPARE2(j+1,1); BLEND(j,0,6.0); } /* Middle */ for (j = 1; j < h-1; j++) { for (k = 1; k < w-1; k++) { opacity = 0; COMPARE2(j-1,k-1); COMPARE2(j,k-1); COMPARE2(j+1,k-1); COMPARE2(j-1,k); COMPARE2(j,k); COMPARE2(j+1,k); COMPARE2(j-1,k+1); COMPARE2(j,k+1); COMPARE2(j+1,k+1); BLEND(j,k,9.0); } } /* Right edge */ for (j = 1; j < h-1; j++) { opacity = 0; COMPARE2(j-1,w-1); COMPARE2(j,w-1); COMPARE2(j+1,w-1); COMPARE2(j-1,w-2); COMPARE2(j,w-2); COMPARE2(j+1,w-2); BLEND(j,w-1,6.0); } /* Bottom left corner */ opacity = 0; COMPARE2(h-1,0); COMPARE2(h-1,1); COMPARE2(h-2,0); COMPARE2(h-2,1); BLEND(h-1,0,4.0); /* Bottom edge */ for (k = 1; k < w-1; k++) { opacity = 0; COMPARE2(h-1,k-1); COMPARE2(h-1,k); COMPARE2(h-1,k+1); COMPARE2(h-2,k-1); COMPARE2(h-2,k); COMPARE2(h-2,k+1); BLEND(h-1,k,6.0); } /* Bottom right corner */ opacity = 0; COMPARE2(h-1,w-1); COMPARE2(h-1,w-2); COMPARE2(h-2,w-1); COMPARE2(h-2,w-2); BLEND(h-1,w-1,4.0); } } else { switch(incoming->get_color_model()) { case BC_RGB_FLOAT: SHAPEWIPE(float, 3) break; case BC_RGB888: case BC_YUV888: SHAPEWIPE(unsigned char, 3) break; case BC_RGBA_FLOAT: SHAPEWIPE(float, 4) break; case BC_RGBA8888: case BC_YUVA8888: SHAPEWIPE(unsigned char, 4) break; case BC_RGB161616: case BC_YUV161616: SHAPEWIPE(uint16_t, 3) break; case BC_RGBA16161616: case BC_YUVA16161616: SHAPEWIPE(uint16_t, 4) break; } } return 0; }
void gPixmap::blit(const gPixmap &src, ePoint pos, const gRegion &clip, int flag) { for (unsigned int i=0; i<clip.rects.size(); ++i) { eRect area=eRect(pos, src.size()); area&=clip.rects[i]; area&=eRect(ePoint(0, 0), size()); if ((area.width()<0) || (area.height()<0)) continue; eRect srcarea=area; srcarea.moveBy(-pos.x(), -pos.y()); if ((surface->data_phys && src.surface->data_phys) && (gAccel::getInstance())) if (!gAccel::getInstance()->blit(surface, src.surface, area.topLeft(), srcarea, flag)) continue; if ((surface->bpp == 8) && (src.surface->bpp==8)) { __u8 *srcptr=(__u8*)src.surface->data; __u8 *dstptr=(__u8*)surface->data; srcptr+=srcarea.left()*src.surface->bypp+srcarea.top()*src.surface->stride; dstptr+=area.left()*surface->bypp+area.top()*surface->stride; for (int y=0; y<area.height(); y++) { if (flag & (blitAlphaTest|blitAlphaBlend)) { // no real alphatest yet int width=area.width(); unsigned char *src=(unsigned char*)srcptr; unsigned char *dst=(unsigned char*)dstptr; // use duff's device here! while (width--) { if (!*src) { src++; dst++; } else *dst++=*src++; } } else memcpy(dstptr, srcptr, area.width()*surface->bypp); srcptr+=src.surface->stride; dstptr+=surface->stride; } } else if ((surface->bpp == 32) && (src.surface->bpp==32)) { __u32 *srcptr=(__u32*)src.surface->data; __u32 *dstptr=(__u32*)surface->data; srcptr+=srcarea.left()+srcarea.top()*src.surface->stride/4; dstptr+=area.left()+area.top()*surface->stride/4; for (int y=0; y<area.height(); y++) { if (flag & blitAlphaTest) { int width=area.width(); unsigned long *src=(unsigned long*)srcptr; unsigned long *dst=(unsigned long*)dstptr; while (width--) { if (!((*src)&0xFF000000)) { src++; dst++; } else *dst++=*src++; } } else if (flag & blitAlphaBlend) { // uh oh. this is only until hardware accel is working. int width=area.width(); // ARGB color space! unsigned char *src=(unsigned char*)srcptr; unsigned char *dst=(unsigned char*)dstptr; #define BLEND(x, y, a) (y + ((x-y) * a)/256) while (width--) { unsigned char sa = src[3]; unsigned char sr = src[2]; unsigned char sg = src[1]; unsigned char sb = src[0]; unsigned char da = dst[3]; unsigned char dr = dst[2]; unsigned char dg = dst[1]; unsigned char db = dst[0]; dst[3] = BLEND(0xFF, da, sa); dst[2] = BLEND(sr, dr, sa); dst[1] = BLEND(sg, dg, sa); dst[0] = BLEND(sb, db, sa); #undef BLEND src += 4; dst += 4; } } else memcpy(dstptr, srcptr, area.width()*surface->bypp); srcptr+=src.surface->stride/4; dstptr+=surface->stride/4; } } else if ((surface->bpp == 32) && (src.surface->bpp==8)) { __u8 *srcptr=(__u8*)src.surface->data; __u8 *dstptr=(__u8*)surface->data; // !! __u32 pal[256]; for (int i=0; i<256; ++i) { if (src.surface->clut.data && (i<src.surface->clut.colors)) pal[i]=(src.surface->clut.data[i].a<<24)|(src.surface->clut.data[i].r<<16)|(src.surface->clut.data[i].g<<8)|(src.surface->clut.data[i].b); else pal[i]=0x010101*i; #if defined(__sh__) //printf("%s:%d col = %08X\n", __FUNCTION__, __LINE__, pal[i]); if((pal[i]&0xFF000000) >= 0xE0000000) pal[i] = 0xFF000000; #endif pal[i]^=0xFF000000; } srcptr+=srcarea.left()*src.surface->bypp+srcarea.top()*src.surface->stride; dstptr+=area.left()*surface->bypp+area.top()*surface->stride; for (int y=0; y<area.height(); y++) { int width=area.width(); unsigned char *psrc=(unsigned char*)srcptr; __u32 *dst=(__u32*)dstptr; if (flag & blitAlphaTest) blit_8i_to_32_at(dst, psrc, pal, width); else if (flag & blitAlphaBlend) blit_8i_to_32_ab(dst, psrc, pal, width); else blit_8i_to_32(dst, psrc, pal, width); srcptr+=src.surface->stride; dstptr+=surface->stride; } } else eWarning("cannot blit %dbpp from %dbpp", surface->bpp, src.surface->bpp); } }
mlib_status __mlib_ImageBlendRGBA2ARGB( mlib_image *dst, const mlib_image *src) { mlib_type type; mlib_u8 *sl, *dl; mlib_s32 slb, dlb, nchan, width, height; mlib_s32 i, j, ii, off; P_TYPE *sp, *dp; P_TYPE ss, aa, ds, dd, d_h, d_l; P_TYPE mzero, const255, mask64, d_half; MLIB_IMAGE_CHECK(dst); MLIB_IMAGE_CHECK(src); MLIB_IMAGE_FULL_EQUAL(dst, src); MLIB_IMAGE_GET_ALL_PARAMS(dst, type, nchan, width, height, dlb, dl); slb = mlib_ImageGetStride(src); sl = mlib_ImageGetData(src); if (type != MLIB_BYTE || nchan != 4) { return (MLIB_FAILURE); } mzero = _mm_setzero_si128(); const255 = _mm_set1_epi32(0x00ff00ff); mask64 = _mm_set1_epi32(0xffffff00); d_half = _mm_set1_epi32(0x00800080); for (j = 0; j < height; j++) { P_TYPE alp, a0, a1, ralp, s0, s1, d0, d1, drnd; mlib_m128 s0u, s1u; sp = (void *)sl; dp = (void *)dl; if (!(((mlib_s32)sp | (mlib_s32)dp) & 15)) { for (i = 0; i < (width / 4); i++) { ss = _mm_load_si128(sp); dd = _mm_load_si128(dp); s0 = _mm_unpacklo_epi8(ss, mzero); a0 = _mm_shufflelo_epi16(s0, 0xff); a0 = _mm_shufflehi_epi16(a0, 0xff); s0 = _mm_shufflelo_epi16(s0, 0x93); s0 = _mm_shufflehi_epi16(s0, 0x93); BLEND(d_h, a0, s0, _mm_unpacklo_epi8(dd, mzero)); s1 = _mm_unpackhi_epi8(ss, mzero); a1 = _mm_shufflelo_epi16(s1, 0xff); a1 = _mm_shufflehi_epi16(a1, 0xff); s1 = _mm_shufflelo_epi16(s1, 0x93); s1 = _mm_shufflehi_epi16(s1, 0x93); BLEND(d_l, a1, s1, _mm_unpackhi_epi8(dd, mzero)); d_h = _mm_packus_epi16(d_h, d_l); d_h = _mm_or_si128(_mm_and_si128(mask64, d_h), _mm_andnot_si128(mask64, dd)); _mm_store_si128(dp, d_h); sp++; dp++; } } else { for (i = 0; i < (width / 4); i++) { #if 0 ss = _mm_loadu_si128(sp); s0 = _mm_unpacklo_epi8(ss, mzero); s1 = _mm_unpackhi_epi8(ss, mzero); #else s0u.m128d = _mm_load_sd((mlib_d64 *)sp); s1u.m128d = _mm_load_sd((mlib_d64 *)sp + 1); s0 = _mm_unpacklo_epi8(s0u.m128i, mzero); s1 = _mm_unpacklo_epi8(s1u.m128i, mzero); #endif dd = _mm_loadu_si128(dp); a0 = _mm_shufflelo_epi16(s0, 0xff); a0 = _mm_shufflehi_epi16(a0, 0xff); s0 = _mm_shufflelo_epi16(s0, 0x93); s0 = _mm_shufflehi_epi16(s0, 0x93); BLEND(d_h, a0, s0, _mm_unpacklo_epi8(dd, mzero)); a1 = _mm_shufflelo_epi16(s1, 0xff); a1 = _mm_shufflehi_epi16(a1, 0xff); s1 = _mm_shufflelo_epi16(s1, 0x93); s1 = _mm_shufflehi_epi16(s1, 0x93); BLEND(d_l, a1, s1, _mm_unpackhi_epi8(dd, mzero)); d_h = _mm_packus_epi16(d_h, d_l); d_h = _mm_or_si128(_mm_and_si128(mask64, d_h), _mm_andnot_si128(mask64, dd)); #if 1 _mm_storeu_si128(dp, d_h); #else s0u.m128i = d_h; s1u.m128i = _mm_shuffle_epi32(d_h, 0x3e); _mm_store_sd((mlib_d64 *)dp, s0u.m128d); _mm_store_sd((mlib_d64 *)dp + 1, s1u.m128d); #endif sp++; dp++; } } if (width & 3) { s0u.m128d = _mm_load_sd((mlib_d64 *)sp); s1u.m128d = _mm_load_sd((mlib_d64 *)sp + 1); s0 = _mm_unpacklo_epi8(s0u.m128i, mzero); s1 = _mm_unpacklo_epi8(s1u.m128i, mzero); dd = _mm_loadu_si128(dp); a0 = _mm_shufflelo_epi16(s0, 0xff); a0 = _mm_shufflehi_epi16(a0, 0xff); s0 = _mm_shufflelo_epi16(s0, 0x93); s0 = _mm_shufflehi_epi16(s0, 0x93); BLEND(d_h, a0, s0, _mm_unpacklo_epi8(dd, mzero)); a1 = _mm_shufflelo_epi16(s1, 0xff); a1 = _mm_shufflehi_epi16(a1, 0xff); s1 = _mm_shufflelo_epi16(s1, 0x93); s1 = _mm_shufflehi_epi16(s1, 0x93); BLEND(d_l, a1, s1, _mm_unpackhi_epi8(dd, mzero)); d_h = _mm_packus_epi16(d_h, d_l); d_h = _mm_or_si128(_mm_and_si128(mask64, d_h), _mm_andnot_si128(mask64, dd)); for (ii = 0; ii < (width & 3); ii++) { ((mlib_s32 *)dp)[ii] = ((mlib_s32 *)&d_h)[ii]; } } sl += slb; dl += dlb; } return (MLIB_SUCCESS); }