XMFLOAT4 TransferFunction::operator()(int isoValue) {
	float alp = _a(isoValue) < 0 ? 0 : (_a(isoValue) > 1 ? 1 : _a(isoValue));
	float red = _r(isoValue) < 0 ? 0 : (_r(isoValue) > 1 ? 1 : _r(isoValue));
	float gre = _g(isoValue) < 0 ? 0 : (_g(isoValue) > 1 ? 1 : _g(isoValue));
	float blu = _b(isoValue) < 0 ? 0 : (_b(isoValue) > 1 ? 1 : _b(isoValue));
	return XMFLOAT4(red, gre, blu, alp);
}
Ejemplo n.º 2
0
double _phiElec(int i, unifac_solution *s)
{
    int j;
    double numer, denom = 0;
    numer = s->xi[i] * pow(_r(s->m[i]), 3./4.);
    for(j=0; j<s->nsolutes; j++)
        denom += s->xi[j] * pow(_r(s->m[j]), 3./4.);
    return numer/denom;
}
void
SymmAnisotropicElasticityTensor::form_r_matrix()
{
  Real phi1 = _euler_angle[0] * (libMesh::pi / 180.0);
  Real phi = _euler_angle[1] * (libMesh::pi / 180.0);
  Real phi2 = _euler_angle[2] * (libMesh::pi / 180.0);

  Real cp1 = std::cos(phi1);
  Real cp2 = std::cos(phi2);
  Real cp = std::cos(phi);

  Real sp1 = std::sin(phi1);
  Real sp2 = std::sin(phi2);
  Real sp = std::sin(phi);

  _r(0, 0) = cp1 * cp2 - sp1 * sp2 * cp;
  _r(0, 1) = sp1 * cp2 + cp1 * sp2 * cp;
  _r(0, 2) = sp2 * sp;
  _r(1, 0) = -cp1 * sp2 - sp1 * cp2 * cp;
  _r(1, 1) = -sp1 * sp2 + cp1 * cp2 * cp;
  _r(1, 2) = cp2 * sp;
  _r(2, 0) = sp1 * sp;
  _r(2, 1) = -cp1 * sp;
  _r(2, 2) = cp;
}
void
SymmAnisotropicElasticityTensor::form_rotational_q_matrix()
{

  for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j)
      for (int k = 0; k < 3; ++k)
        for (int l = 0; l < 3; ++l)
          _q(((i * 3) + k), ((j * 3) + l)) = _r(i, j) * _r(k, l);

  /*for (int p = 0; p < 9; ++p)
    for (int q = 0; q < 9; ++q)
    _qt(q,p) = _q(p,q);*/
}
Ejemplo n.º 5
0
/**
 * The L_i value is calculated from q, r, and z, where q and r are defined
 * above and z is the coordination number. Here, z is assumed to be equal to
 * ten.
 * \f[
 * L_i = \frac{z}{2}(r_i - q_i) - (r_i -1)
 * \f]
 * @param molec Molecule to calculate the value for
 * @returns L_i
 */
double _L(unifac_molec molec)
{
    double ri, qi;
    ri = _r(molec);
    qi = _q(molec);
    return Z/2*(ri - qi) - (ri - 1);
}
Ejemplo n.º 6
0
void	CRendererDX::Text( spCBaseFont _spFont, const std::string &_text, const Base::Math::CVector4 &_color, const Base::Math::CRect &_rect, uint32 _flags )
{
    ASSERT( _text != "" );

	if( _spFont == NULL )
		return;

	const fp4 w05 = (fp4)m_spDisplay->Width() * 0.5f;
	const fp4 h05 = (fp4)m_spDisplay->Height() * 0.5f;
	Base::Math::CRect _r( lerpMacro( -w05, w05, _rect.m_X0 ), lerpMacro( -h05, h05, _rect.m_Y0 ), lerpMacro( -w05, w05, _rect.m_X1 ), lerpMacro( -h05, h05, _rect.m_Y1 ) );

	RECT r = { (LONG)_r.m_X0, (LONG)_r.m_Y0, (LONG)_r.m_X1, (LONG)_r.m_Y1, };

    DWORD d3dFlags = DT_NOCLIP;

	if( _flags & CBaseFont::Bottom )		d3dFlags |= DT_BOTTOM; // bug if CBaseFont::Bottom == 0 because of check _flag & 0 != 0
    if( _flags & CBaseFont::Top )			d3dFlags |= DT_TOP;
    if( _flags & CBaseFont::Center )		d3dFlags |= DT_CENTER;
    if( _flags & CBaseFont::Left )			d3dFlags |= DT_LEFT;
    if( _flags & CBaseFont::Right )			d3dFlags |= DT_RIGHT;
    if( _flags & CBaseFont::VCenter )		d3dFlags |= DT_VCENTER;
    if( _flags & CBaseFont::NoClip )		d3dFlags |= DT_NOCLIP;
    if( _flags & CBaseFont::ExpandTabs )	d3dFlags |= DT_EXPANDTABS;
    if( _flags & CBaseFont::WordBreak )		d3dFlags |= DT_WORDBREAK;

	DWORD d3dColor = D3DCOLOR_COLORVALUE( _color.m_X, _color.m_Y, _color.m_Z, _color.m_W );

	spCFontDX	spDXFont = _spFont;
	ID3DXFont	*pDXFont = spDXFont->GetDXFont();
    ASSERT( pDXFont );

    m_pSprite->Begin( D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE | D3DXSPRITE_OBJECTSPACE | D3DXSPRITE_DO_NOT_ADDREF_TEXTURE );
    pDXFont->DrawTextA( m_pSprite, (const char *)_text.c_str(), -1, &r, d3dFlags, d3dColor );
    m_pSprite->End();
}
Ejemplo n.º 7
0
static void assRender(VSFrameRef *dst, VSFrameRef *alpha, const VSAPI *vsapi,
                      ASS_Image *img)
{
    uint8_t *planes[4];
    int strides[4], p;

    for(p = 0; p < 4; p++) {
        VSFrameRef *fr = p == 3 ? alpha : dst;

        planes[p] = vsapi->getWritePtr(fr, p % 3);
        strides[p] = vsapi->getStride(fr, p % 3);
        memset(planes[p], 0, strides[p] * vsapi->getFrameHeight(fr, p % 3));
    }

    while(img) {
        uint8_t *dstp[4], *alphap, *sp, color[4];
        uint16_t outa;
        int x, y, k;

        if(img->w == 0 || img->h == 0) {
            img = img->next;
            continue;
        }

        color[0] = _r(img->color);
        color[1] = _g(img->color);
        color[2] = _b(img->color);
        color[3] = _a(img->color);

        dstp[0] = planes[0] + (strides[0] * img->dst_y) + img->dst_x;
        dstp[1] = planes[1] + (strides[1] * img->dst_y) + img->dst_x;
        dstp[2] = planes[2] + (strides[2] * img->dst_y) + img->dst_x;
        dstp[3] = planes[3] + (strides[3] * img->dst_y) + img->dst_x;
        alphap = dstp[3];
        sp = img->bitmap;

        for(y = 0; y < img->h; y++) {
            for(x = 0; x < img->w; x++) {
                k = div255(sp[x] * color[3]);
                outa = k * 255 + (alphap[x] * (255 - k));

                if(outa != 0) {
                    dstp[0][x] = blend(k, color[0], alphap[x], dstp[0][x], outa);
                    dstp[1][x] = blend(k, color[1], alphap[x], dstp[1][x], outa);
                    dstp[2][x] = blend(k, color[2], alphap[x], dstp[2][x], outa);
                    dstp[3][x] = div255(outa);
                }
            }

            dstp[0] += strides[0];
            dstp[1] += strides[1];
            dstp[2] += strides[2];
            dstp[3] += strides[3];
            alphap += strides[3];
            sp += img->stride;
        }

        img = img->next;
    }
}
Ejemplo n.º 8
0
static void blend_single(SDL_Surface * frame, ASS_Image *img)
{
    int x, y;
    unsigned char opacity = 255 - _a(img->color);
    unsigned char r = _r(img->color);
    unsigned char g = _g(img->color);
    unsigned char b = _b(img->color);

    unsigned char *src;
    unsigned char *dst;

    src = img->bitmap;
    dst = frame->pixels;

    for (y = 0; y < img->h; ++y) {
        for (x = 0; x < img->w; ++x) {
            unsigned k = ((unsigned) src[x]) * opacity / 255;
            // possible endianness problems
            dst[x * 4] = (k * b + (255 - k) * dst[x * 4]) / 255;
            dst[x * 4 + 1] = (k * g + (255 - k) * dst[x * 4 + 1]) / 255;
            dst[x * 4 + 2] = (k * r + (255 - k) * dst[x * 4 + 2]) / 255;
            dst[x * 4 + 3] = k;
        }
        src += img->stride;
        dst += frame->pitch;
    }
}
Ejemplo n.º 9
0
 Z3_ast Z3_API Z3_algebraic_root(Z3_context c, Z3_ast a, unsigned k) {
     Z3_TRY;
     LOG_Z3_algebraic_root(c, a, k);
     RESET_ERROR_CODE();
     CHECK_IS_ALGEBRAIC_X(a, 0);
     if (k % 2 == 0) {
         if ((is_rational(c, a) && get_rational(c, a).is_neg()) ||
             (!is_rational(c, a) && am(c).is_neg(get_irrational(c, a)))) {
             SET_ERROR_CODE(Z3_INVALID_ARG);
             RETURN_Z3(0);
         }
     }
     algebraic_numbers::manager & _am = am(c);
     scoped_anum _r(_am);
     if (is_rational(c, a)) {
         scoped_anum av(_am);                                     
         _am.set(av, get_rational(c, a).to_mpq());   
         _am.root(av, k, _r);
     }
     else {
         algebraic_numbers::anum const & av = get_irrational(c, a);
         _am.root(av, k, _r);
     }
     expr * r = au(c).mk_numeral(_r, false);
     mk_c(c)->save_ast_trail(r);
     RETURN_Z3(of_ast(r));
     Z3_CATCH_RETURN(0);
 }
Ejemplo n.º 10
0
static void blend_single(image_t * frame, ASS_Image *img)
{
    int x, y;
    unsigned char opacity = 255 - _a(img->color);
    unsigned char r = _r(img->color);
    unsigned char g = _g(img->color);
    unsigned char b = _b(img->color);

    unsigned char *src;
    unsigned char *dst;

    src = img->bitmap;
    dst = frame->buffer + img->dst_y * frame->stride + img->dst_x * 3;
    for (y = 0; y < img->h; ++y) {
        for (x = 0; x < img->w; ++x) {
            unsigned k = ((unsigned) src[x]) * opacity / 255;
            // possible endianness problems
            dst[x * 3] = (k * b + (255 - k) * dst[x * 3]) / 255;
            dst[x * 3 + 1] = (k * g + (255 - k) * dst[x * 3 + 1]) / 255;
            dst[x * 3 + 2] = (k * r + (255 - k) * dst[x * 3 + 2]) / 255;
        }
        src += img->stride;
        dst += frame->stride;
    }
}
/// @brief Draw subtitles
/// @param frame
/// @param time
/// @return
///
void LibassSubtitlesProvider::DrawSubtitles(AegiVideoFrame &frame,double time) {
	// Set size
	ass_set_frame_size(ass_renderer, frame.w, frame.h);

	// Get frame
	ASS_Image* img = ass_render_frame(ass_renderer, ass_track, int(time * 1000), NULL);

	// libass actually returns several alpha-masked monochrome images.
	// Here, we loop through their linked list, get the colour of the current, and blend into the frame.
	// This is repeated for all of them.
	while (img) {
		// Get colours
		unsigned int opacity = 255 - ((unsigned int)_a(img->color));
		unsigned int r = (unsigned int)_r(img->color);
		unsigned int g = (unsigned int)_g(img->color);
		unsigned int b = (unsigned int) _b(img->color);

		// Prepare copy
		int src_stride = img->stride;
		int dst_stride = frame.pitch;
		const unsigned char *src = img->bitmap;

		unsigned char *dst = frame.data;
		if (frame.flipped) {
			dst += dst_stride * (frame.h - 1);
			dst_stride *= -1;
		}
		dst += (img->dst_y * dst_stride + img->dst_x * 4);

		// Copy image to destination frame
		for (int y = 0; y < img->h; y++) {
			unsigned char *dstp = dst;

			for (int x = 0; x < img->w; ++x) {
				unsigned int k = ((unsigned)src[x]) * opacity / 255;
				unsigned int ck = 255 - k;

				*dstp = (k * b + ck * *dstp) / 255;
				++dstp;

				*dstp = (k * g + ck * *dstp) / 255;
				++dstp;

				*dstp = (k * r + ck * *dstp) / 255;
				++dstp;

				++dstp;
			}

			dst += dst_stride;
			src += src_stride;
		}

		// Next image
		img = img->next;
	}
}
Ejemplo n.º 12
0
bool isSpriteContainPoint(Sprite *_sprite, Point _point, Point &_outPoint)
{
    _outPoint = _sprite->convertToNodeSpace(_point);

    Size _s  = _sprite->getContentSize();
    Rect _r(0, 0, _s.width, _s.height);

    return _r.containsPoint(_outPoint);
}
Ejemplo n.º 13
0
static int writeData(void* _call)
{
    unsigned char r;
    unsigned char g;
    unsigned char b;
    unsigned char a;
    int x,y;
    int res = 0;
    unsigned char* dst;
    
    WriterFBCallData_t* call = (WriterFBCallData_t*) _call;
    
    fb_printf(100, "\n");

    if (call == NULL)
    {
        fb_err("call data is NULL...\n");
        return 0;
    }

    if (call->destination == NULL)
    {
        fb_err("file pointer < 0. ignoring ...\n");
        return 0;
    }
    
    if (call->data != NULL)
    {
        unsigned int opacity = 255 - ((unsigned int)_a(call->color));
        unsigned int r = (unsigned int)_r(call->color);
        unsigned int g = (unsigned int)_g(call->color);
        unsigned int b = (unsigned int) _b(call->color);
        int src_stride = call->Stride;
        int dst_stride = call->destStride;
        int dst_delta  = dst_stride - call->Width*4;
        int x,y;
        const unsigned char *src = call->data;
        unsigned char *dst = call->destination + (call->y * dst_stride + call->x * 4);
	//uint32_t *dst = call->destination + call->y * dst_stride + call->x;
        unsigned int k,ck,t;

	static uint32_t last_color = 0, colortable[256];

	if (last_color != call->color) {
		// call->color is rgba, our spark frame buffer is argb
		uint32_t c = call->color >> 8, a = 255 - (call->color & 0xff);
		int i;
		for (i = 0; i < 256; i++) {
			uint32_t k = (a * i) >> 8;
			colortable[i] = k ? (c | (k << 24)) : 0;
		}
		last_color = call->color;
	}
Ejemplo n.º 14
0
// render 1 ass image into a 32bit QImage with alpha channel.
//use dstX, dstY instead of img->dst_x/y because image size is small then ass renderer size
void RenderASS(QImage *image, const SubImage& img, int dstX, int dstY)
{
    const quint8 a = 255 - _a(img.color);
    if (a == 0)
        return;
    const quint8 r = _r(img.color);
    const quint8 g = _g(img.color);
    const quint8 b = _b(img.color);
    const quint8 *src = (const quint8*)img.data.constData();
    // use QRgb to avoid endian issue
    QRgb *dst = (QRgb*)image->constBits() + dstY * image->width() + dstX;
    // k*src+(1-k)*dst
    for (int y = 0; y < img.height(); ++y) {
        for (int x = 0; x < img.width(); ++x) {
            const unsigned k = ((unsigned) src[x])*a/255;
#if USE_QRGBA
            const unsigned A = qAlpha(dst[x]);
#else
            quint8 *c = (quint8*)(&dst[x]);
            const unsigned A = ARGB32_A(c);
#endif
            if (A == 0) { // dst color can be ignored
#if USE_QRGBA
                 dst[x] = qRgba(r, g, b, k);
#else
                 ARGB32_SET(c, r, g, b, k);
#endif //USE_QRGBA
            } else if (k == 0) { //no change
                //dst[x] = qRgba(qRed(dst[x])), qGreen(dst[x]), qBlue(dst[x]), qAlpha(dst[x])) == dst[x];
            } else if (k == 255) {
#if USE_QRGBA
                dst[x] = qRgba(r, g, b, k);
#else
                ARGB32_SET(c, r, g, b, k);
#endif //USE_QRGBA
            } else {
                // c=k*dc/255=k*dc/256 * (1-1/256), -1<err(c) = k*dc/256^2<1, -1 is bad!
#if USE_QRGBA
                // no need to &0xff because always be 0~255
                dst[x] += qRgba2(k*(r-qRed(dst[x]))/255, k*(g-qGreen(dst[x]))/255, k*(b-qBlue(dst[x]))/255, k*(a-A)/255);
#else
                const unsigned R = ARGB32_R(c);
                const unsigned G = ARGB32_G(c);
                const unsigned B = ARGB32_B(c);
                ARGB32_ADD(c, r == R ? 0 : k*(r-R)/255, g == G ? 0 : k*(g-G)/255, b == B ? 0 : k*(b-B)/255, a == A ? 0 : k*(a-A)/255);
#endif
            }
        }
        src += img.stride();
        dst += image->width();
    }
}
Ejemplo n.º 15
0
// C[i] = C'[i] = (k*c[i]+(255-k)*C[i])/255 = C[i] + k*(c[i]-C[i])/255, min(c[i],C[i]) <= C'[i] <= max(c[i],C[i])
void SubtitleProcessorLibASS::renderASS32(QImage *image, ASS_Image *img, int dstX, int dstY)
{
    const quint8 a = 255 - _a(img->color);
    if (a == 0)
        return;
    const quint8 r = _r(img->color);
    const quint8 g = _g(img->color);
    const quint8 b = _b(img->color);
    quint8 *src = img->bitmap;
    // use QRgb to avoid endian issue
    QRgb *dst = (QRgb*)image->bits() + dstY * image->width() + dstX;
    for (int y = 0; y < img->h; ++y) {
        for (int x = 0; x < img->w; ++x) {
            const unsigned k = ((unsigned) src[x])*a/255;
#if USE_QRGBA
            const unsigned A = qAlpha(dst[x]);
#else
            quint8 *c = (quint8*)(&dst[x]);
            const unsigned A = ARGB32_A(c);
#endif
            if (A == 0) { // dst color can be ignored
#if USE_QRGBA
                 dst[x] = qRgba(r, g, b, k);
#else
                 ARGB32_SET(c, r, g, b, k);
#endif //USE_QRGBA
            } else if (k == 0) { //no change
                //dst[x] = qRgba(qRed(dst[x])), qGreen(dst[x]), qBlue(dst[x]), qAlpha(dst[x])) == dst[x];
            } else if (k == 255) {
#if USE_QRGBA
                dst[x] = qRgba(r, g, b, k);
#else
                ARGB32_SET(c, r, g, b, k);
#endif //USE_QRGBA
            } else {
#if USE_QRGBA
                // no need to &0xff because always be 0~255
                dst[x] += qRgba2(k*(r-qRed(dst[x]))/255, k*(g-qGreen(dst[x]))/255, k*(b-qBlue(dst[x]))/255, k*(a-A)/255);
#else
                const unsigned R = ARGB32_R(c);
                const unsigned G = ARGB32_G(c);
                const unsigned B = ARGB32_B(c);
                ARGB32_ADD(c, r == R ? 0 : k*(r-R)/255, g == G ? 0 : k*(g-G)/255, b == B ? 0 : k*(b-B)/255, a == A ? 0 : k*(a-A)/255);
#endif
            }
        }
        src += img->stride;
        dst += image->width();
    }
}
Ejemplo n.º 16
0
void readers::updateReaders(){
    for (int a = ui.tableWidget_readers->rowCount(); a >= 0; a--){
        ui.tableWidget_readers->removeRow(a);
    }
    QSqlQuery _r("select readers.id, readers.fam, readers.ima, readers.otc, readers.date_r, readers.num, readers.phone, "
                 "readers.address, readers.doc from readers order by readers.fam ");
    int row = 0;
    while (_r.next()){
        ui.tableWidget_readers->insertRow(row);
        for (int col = 0; col < 9; col++){
            QTableWidgetItem *item = new QTableWidgetItem(_r.value(col).toString());
            ui.tableWidget_readers->setItem(row, col, item);
        }
        row++;
    }
}
void
SymmAnisotropicElasticityTensor::show_r_matrix()
{
  printf("\nSymmAnisotropicElasticityTensor::show_r_matrix()  Euler angles are (%f, %f, %f)\n",
         _euler_angle[0],
         _euler_angle[1],
         _euler_angle[2]);

  for (int j = 0; j < 3; ++j)
  {
    printf("  ");
    for (int i = 0; i < 3; ++i)
    {
      printf("%8.4f  ", _r(i, j));
    }
    printf("\n");
  }
}
Ejemplo n.º 18
0
 Z3_ast_vector Z3_API Z3_polynomial_subresultants(Z3_context c, Z3_ast p, Z3_ast q, Z3_ast x) {
     Z3_TRY;
     LOG_Z3_polynomial_subresultants(c, p, q, x);
     RESET_ERROR_CODE();
     polynomial::manager & pm = mk_c(c)->pm();
     polynomial_ref _p(pm), _q(pm);
     polynomial::scoped_numeral d(pm.m());
     default_expr2polynomial converter(mk_c(c)->m(), pm);
     if (!converter.to_polynomial(to_expr(p), _p, d) ||
         !converter.to_polynomial(to_expr(q), _q, d)) {
         SET_ERROR_CODE(Z3_INVALID_ARG);
         return 0;
     }
     Z3_ast_vector_ref* result = alloc(Z3_ast_vector_ref, mk_c(c)->m());
     mk_c(c)->save_object(result);
     if (converter.is_var(to_expr(x))) {
         expr2var const & mapping = converter.get_mapping();
         unsigned v_x = mapping.to_var(to_expr(x));
         polynomial_ref_vector rs(pm);
         polynomial_ref r(pm);
         expr_ref _r(mk_c(c)->m());
         {
             cancel_eh<polynomial::manager> eh(pm);
             api::context::set_interruptable si(*(mk_c(c)), eh);
             scoped_timer timer(mk_c(c)->params().m_timeout, &eh);
             pm.psc_chain(_p, _q, v_x, rs);
         }
         for (unsigned i = 0; i < rs.size(); i++) {
             r = rs.get(i);
             converter.to_expr(r, true, _r);
             result->m_ast_vector.push_back(_r);
         }
     }
     RETURN_Z3(of_ast_vector(result));
     Z3_CATCH_RETURN(0);
 }
static int writeData(void* _call)
{
    unsigned char r;
    unsigned char g;
    unsigned char b;
    unsigned char a;
    int x,y;
    int res = 0;
    unsigned char* dst;
    
    WriterFBCallData_t* call = (WriterFBCallData_t*) _call;
    
    fb_printf(100, "\n");

    if (call == NULL)
    {
        fb_err("call data is NULL...\n");
        return 0;
    }

    if (call->destination == NULL)
    {
        fb_err("file pointer < 0. ignoring ...\n");
        return 0;
    }
    
    if (call->data != NULL)
    {
        unsigned int opacity = 255 - ((unsigned int)_a(call->color));
        unsigned int r = (unsigned int)_r(call->color);
        unsigned int g = (unsigned int)_g(call->color);
        unsigned int b = (unsigned int) _b(call->color);
        int src_stride = call->Stride;
        int dst_stride = call->destStride;
        int dst_delta  = dst_stride - call->Width*4;
        int x,y;
        const unsigned char *src = call->data;
        unsigned char *dst = call->destination + (call->y * dst_stride + call->x * 4);
        unsigned int k,ck,t;

        fb_printf(100, "x           %d\n", call->x);
        fb_printf(100, "y           %d\n", call->y);
        fb_printf(100, "width       %d\n", call->Width);
        fb_printf(100, "height      %d\n", call->Height);
        fb_printf(100, "stride      %d\n", call->Stride);
        fb_printf(100, "color       %d\n", call->color);
        fb_printf(100, "data        %p\n", call->data);
        fb_printf(100, "dest        %p\n", call->destination);
        fb_printf(100, "dest.stride %d\n", call->destStride);

        fb_printf(100, "r 0x%hhx, g 0x%hhx, b 0x%hhx, a 0x%hhx, opacity %d\n", r, g, b, a, opacity);

        for (y=0;y<call->Height;y++)
        {
            for (x = 0; x < call->Width; x++)
            {
                k = ((unsigned)src[x]) * opacity / 255;
                ck = 255 - k;
                t = *dst;
                *dst++ = (k*b + ck*t) / 255;
                t = *dst;
                *dst++ = (k*g + ck*t) / 255;
                t = *dst;
                *dst++ = (k*r + ck*t) / 255;
                *dst++ = 0;
            }

            dst += dst_delta;
            src += src_stride;
        }
    } else
    {
         for (y = 0; y < call->Height; y++)
                memset(call->destination + ((call->y + y) * call->destStride) + call->x * 4, 0, call->Width * 4);
    }
 
    fb_printf(100, "< %d\n", res);
    return res;
}
Ejemplo n.º 20
0
		// distance of the centers of spheres
		T distance(const Sphere& rhs) const {
			// move two spheres so that the center of (*this) comes to the origin
			Sphere _r(rhs.x - x, rhs.y - y, rhs.z - z, rhs.r);
			return Vector3D<T>(_r.x, _r.y, _r.z).abs();
		}
Ejemplo n.º 21
0
/* Safe forking/cloning
 *
 * This function takes over the PRE fase of a child process' fork
 * syscall. It then forks the child in a controlled manor ensuring
 * tracy will be able to trace the forked process.
 * This function returns the pid of the new child in new_child upon success.
 *
 * Upon error the return value will be -1 and errno will be set appropriately.
 *
 * FIXME: This function memleaks a page upon failure in the child atm.
 * TODO: This function needs a lot more error handling than it contains now.
 * FIXME: Due to the PTRACE_CHECK macro's if a ptrace fails, we will not
 * restore the original signal handler for SIGUSR1.
 */
int tracy_safe_fork(struct tracy_child *c, pid_t *new_child)
{
    tracy_child_addr_t mmap_ret;
    int status;
    long ip, orig_syscall, orig_trampy_pid_reg;
    struct TRACY_REGS_NAME args, args_ret;
    const long page_size = sysconf(_SC_PAGESIZE);
    pid_t child_pid;
    struct sigaction act, old_sigusr1, old_sigchld;
    sigset_t set, old_set;
    struct timespec timeout;
    siginfo_t info;
    int is_vforking = 0;

    child_pid = -1;

    tracy_debug_current(c);

/*
    puts("SAFE_FORKING!");
*/
    /* First let's allocate a page in the child which we shall use
     * to write a piece of forkcode (see trampy.c) to.
     */
   tracy_mmap(c, &mmap_ret,
            NULL, page_size,
            PROT_READ | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS,
            -1, 0
            );

    /* I know this is FUBAR, but bear with me
     *
     * Check for an error value in the return code/address.
     */
    if (mmap_ret < ((tracy_child_addr_t)NULL) &&
            mmap_ret > ((tracy_child_addr_t)-4096)) {
        errno = -(long)mmap_ret;
        perror("tracy_mmap");
        return -1;
    }
/*
    printf("mmap addr: %p\n", (void*)mmap_ret);
*/

    /* XXX - Debug
    printf("trampy_get_safe_entry() = %p\ntrampy_get_code_size() = %d\n",
        trampy_get_safe_entry(), trampy_get_code_size());
    */

    /* Write the piece of code to the child process */
    if (tracy_write_mem(c, (void*) mmap_ret,
            trampy_get_safe_entry(),
            trampy_get_code_size()) < 0) {
        perror("tracy_write_mem");
        return -1;
    }

    /* Fetch the registers to store the original forking syscall and more importantly
     * the instruction pointer.
     */
    PTRACE_CHECK(PTRACE_GETREGS, c->pid, 0, &args, -1);

    /* Deny so we can set the IP on the denied post and do our own fork in a
     * controlled environment */
    tracy_deny_syscall(c);
    c->denied_nr = 0;
    PTRACE_CHECK(PTRACE_SYSCALL, c->pid, 0, 0, -1);
/*
    puts("DENIED, in PRE");
*/
    waitpid(c->pid, &status, __WALL);
/*
    puts("AFTER DENIED, entered POST");
*/

    /* Okay, the child is now in POST syscall mode, and it has
     * just executed a bogus syscall (getpid) inserted by deny syscall.
     *
     * Setup a fork syscall and point the processor to the injected code.
     */
    /*
     * XXX: We do not have to modify the syscall NR since we use this function
     * for fork, clone and vfork.
    args.TRACY_SYSCALL_REGISTER = __NR_fork;
    args.TRACY_SYSCALL_N = __NR_fork;
    */
    orig_syscall = args.TRACY_SYSCALL_REGISTER;
    orig_trampy_pid_reg = args.TRAMPY_PID_REG;

    printf(_r("Safe forking syscall"));
#if 0
    /* TODO: Fix for ABI */
    printf(_r("Safe forking syscall:")" "_g("%s")"\n", get_syscall_name(args.TRACY_SYSCALL_REGISTER));
#endif

    /* Check if this is a vfork-type syscall */
    if (orig_syscall == __NR_vfork)
        is_vforking = 1;

    /* Clone can also cause vfork behaviour */

#pragma message "getreg(&args, 0, 0) is abi dependent and wrong"
    if (orig_syscall == __NR_clone && get_reg(&args, 0, 0) & CLONE_VFORK) {
        puts(_b("clone with CLONE_VFORK detected, treating as vfork call"));
        is_vforking = 1;
    }

    /* XXX: TODO: Should we place an ARM PTRACE_SET_SYSCALL here? */

    /* XXX: The IP we store here is the IP in the PRE phase of the parent process.
     * At that moment the IP points to the instruction following de syscall.
     */
    ip = args.TRACY_IP_REG;
    args.TRACY_IP_REG = (long)mmap_ret;

    /*
    printf(_b("Pointer data @ IP 0x%lx: 0x%lx")"\n", ip,  ptrace(PTRACE_PEEKDATA, c->pid, ip, NULL));
    printf(_b("Pointer data @ IP-4 0x%lx: 0x%lx")"\n", ip - 4,  ptrace(PTRACE_PEEKDATA, c->pid, ip - 4, NULL));
    */

    PTRACE_CHECK(PTRACE_SETREGS, c->pid, 0, &args, -1);

/*
    printf("The IP was changed from %p to %p\n", (void*)ip, (void*)mmap_ret);

    puts("POST, Entering PRE");
*/

    PTRACE_CHECK(PTRACE_SYSCALL, c->pid, 0, 0, -1);
    waitpid(c->pid, &status, __WALL);

    /* At this moment the child is in PRE mode in the trampy code,
     * trying to execute a sched_yield, which we shall now make
     * into a fork syscall.
     */
    PTRACE_CHECK(PTRACE_GETREGS, c->pid, 0, &args_ret, -1);
/*
    printf("The IP is now %p\n", (void*)args_ret.TRACY_IP_REG);
    printf("Modifying syscall back to fork\n");
*/

    /* TODO: Replace the following with a single call to
     * tracy_modify_syscall().
     */
    args_ret.TRACY_SYSCALL_REGISTER = orig_syscall;
    args_ret.TRACY_SYSCALL_N = orig_syscall;

    /* This stores our pid in a specific register, which will then be used by
     * the new child to inform us of its existence.
     */
    args_ret.TRAMPY_PID_REG = getpid();

    /* On ARM the syscall number is not included in any register, so we have
     * this special ptrace option to modify the syscall
     */
    #ifdef __arm__
    PTRACE_CHECK(PTRACE_SET_SYSCALL, c->pid, 0, (void*)orig_syscall, -1);
    #endif

    PTRACE_CHECK(PTRACE_SETREGS, c->pid, 0, &args_ret, -1);

/*
    puts("PRE, Entering POST");
*/

    /* Setup the blocking of signals to atomically wait for them after ptrace */
    sigemptyset(&set);
    sigaddset(&set, SIGUSR1);
    sigaddset(&set, SIGCHLD);
    pthread_sigmask(SIG_BLOCK, &set, &old_set);

    /* Finally before we execute an actual fork syscall
     * setup the SIGUSR1 handler which is used by trampy to
     * inform us of vforking children
     */
    act.sa_sigaction = _tracer_fork_signal_handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;
    sigaction(SIGUSR1, &act, &old_sigusr1);
    sigaction(SIGCHLD, &act, &old_sigchld);

    /* Now execute the actual fork.
     *
     * Afterwards the parent will immediately come to a halt
     * while the child will wait for us to attach. See 'trampy.c'
     * for more details.
     */
    PTRACE_CHECK(PTRACE_SYSCALL, c->pid, 0, 0, -1);

    /* Now wait for either SIGCHLD from the forker,
     * or SIGUSR1 from the forkee
     */
    /*sigsuspend(&set);*/
    /*pause();*/
    /*sigwait(&set);*/
    /* XXX: The manpage states all threads within the current process must block
     * aforementioned signals, so there might be some trouble caused by using tracy
     * within a multithreaded larger whole. If not all threads block these signals
     * some thread might still handle them before we get to call sigwaitinfo which
     * causes lock-up of this thread in the worst case or otherwise a race condition
     * wherein we never restore the child or the parent in case of vfork().
     */
    while (1) {
        sigwaitinfo(&set, &info);
        /* In case of SIGCHLD the parent or another process might've stopped */
        if (info.si_signo == SIGCHLD && info.si_pid == c->pid) {
            /* The parent has stopped (completed its syscall), in case of vfork
             * this means the vfork failed. If it didn't something that shouldn't
             * happen occurred.
             */
            if (is_vforking) {
                /* FIXME: There must be a more elegant way to handle failure,
                 * which we currently don't do anyway so go.. go.. go..
                 */
                printf(_r("tracy: During vfork(), failure in parent.")"\n");
                child_pid = -1;
                break;
            } else {
                printf(_b("tracy: During fork(), parent returned first.")"\n");
                break;
            }
        }

        /* This is the new child */
        if (info.si_signo == SIGUSR1) {
            printf(_b("Handling SIGUSR1 from process %d, completing safe-fork")
                "\n", info.si_pid);

            /* If we're vforking the parent is now marked frozen */
            if (is_vforking) {
                c->frozen_by_vfork = 1;
                c->orig_trampy_pid_reg = orig_trampy_pid_reg;
                c->orig_pc = ip;
                c->orig_return_code = info.si_pid;
            }

            /* Attach to the new child */
            /*PTRACE_CHECK(PTRACE_ATTACH, info.si_pid, 0, 0, -1);*/
            child_pid = info.si_pid;

            /* Return PID to caller if they're interested. */
            /* XXX: Assignment to child_pid rarely happens, collapse this
             * line with th other somewhere useful.
             */
            if (new_child)
                *new_child = child_pid;
            break;
        }
    }

    /* The trampy register is now restored to the original value */
    args_ret.TRAMPY_PID_REG = orig_trampy_pid_reg;

    /* If we're vforking there is no point in resuming the parent because
     * it is frozen, unless the vfork failed.
     */
    if (!is_vforking || child_pid == -1) {
        waitpid(c->pid, &status, __WALL);

        PTRACE_CHECK(PTRACE_GETREGS, c->pid, 0, &args_ret, -1);

        /*
            printf("The IP is now %p\n", (void*)args_ret.TRACY_IP_REG);
            puts("POST");
        */

        /* FIXME: We don't check if the fork failed
         * which we really should since there is no point in
         * attaching to a failed fork.
         */
        child_pid = args_ret.TRACY_RETURN_CODE;

        /* Return PID to caller if they're interested. */
        if (new_child)
            *new_child = child_pid;

        printf("Fork return value: %d\n", child_pid);

        /* Now point the parent process after the original fork
         * syscall instruction.
         */
        args_ret.TRACY_IP_REG = ip;
        args_ret.TRACY_RETURN_CODE = child_pid;

        PTRACE_CHECK(PTRACE_SETREGS, c->pid, 0, &args_ret, -1);
        printf("Return code set to %d\n", child_pid);

        c->pre_syscall = 0;

        /* TODO Handle possible kill signal from child that might be waiting
         * in the singal set
         */

    } /* End of non-vfork block */

    /* Attach to the new child */
    printf("Attaching to %d...\n", child_pid);

    /* Ptrace guarantees PRE state (? XXX TODO FIXME)*/
    PTRACE_CHECK(PTRACE_ATTACH, child_pid, 0, 0, -1);
    if (waitpid(child_pid, &status, __WALL) == -1) {
        perror("Failure waiting for new child");
    }

/*
    if (ptrace(PTRACE_SETREGS, child_pid, 0, &args))
        perror("SETREGS");
*/

    /* Restore the new child to its original position */
    args.TRACY_IP_REG = ip;
    args.TRACY_RETURN_CODE = 0;

    /* Retrieve stack pointer first.
     * 
     * clone can modify the stack pointer, so the stack pointer
     * needs to be left untouched.
     */
    PTRACE_CHECK(PTRACE_GETREGS, child_pid, 0, &args_ret, -1);
    args.TRACY_STACK_POINTER = args_ret.TRACY_STACK_POINTER;

    /* Now update child registers */
    PTRACE_CHECK(PTRACE_SETREGS, child_pid, 0, &args, -1);

    /* Set enhanced syscall tracing */
    PTRACE_CHECK(PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACESYSGOOD, -1);

    /* Continue the new child */

    /* PTRACE_CHECK(PTRACE_SYSCALL, child_pid, 0, 0, -1); */

    /* Poll for any remaining SIGUSR1 so this cannot kill us in the
     * original process signal mode.
     */
    timeout.tv_sec = 0;
    timeout.tv_nsec = 0;
    sigdelset(&set, SIGCHLD);
    sigtimedwait(&set, &info, &timeout);

    /* Restore the original signal handlers */
    sigaction(SIGUSR1, &old_sigusr1, NULL);
    sigaction(SIGCHLD, &old_sigchld, NULL);

    /* Restore signal mask settings */
    pthread_sigmask(SIG_SETMASK, &old_set, NULL);

    /* TODO: We should now munmap the pages in both the parent and the child.
     * Unless ofc. we created a thread which shares VM in which case we should
     * munmap only once.
     */

    return 0;
}