Пример #1
0
  void update(double time,
              uint32_t* out,
              const uint32_t* in1,
              const uint32_t* in2)
  {
    uint8_t *dst = reinterpret_cast<uint8_t*>(out);
    const uint8_t *src1 = reinterpret_cast<const uint8_t*>(in1);
    const uint8_t *src2 = reinterpret_cast<const uint8_t*>(in2);
    
    for (unsigned int i=0; i<size; ++i)
    {
      uint32_t tmp;
      uint8_t alpha_src1 = src1[3];
      uint8_t alpha_src2 = src2[3];
      uint8_t alpha_dst;
      uint8_t w2 = 0xff ^ alpha_src1; // w2 = 255 - alpha_1

      // compute destination alpha
      alpha_dst = dst[3] = INT_MULT(alpha_src1, alpha_src1, tmp) + INT_MULT3(alpha_src2, alpha_src2, w2, tmp);

       // compute destination values
      if (alpha_dst == 0)
        for (int b=0; b<3; ++b)
          dst[b] = 0;
      else
        for (int b=0; b<3; ++b)
          dst[b] = CLAMP0255( (uint32_t)( (uint32_t) (src1[b] * alpha_src1 + INT_MULT(src2[b], alpha_src2, tmp) * w2) / alpha_dst) );
      
      src1 += 4;
      src2 += 4;
      dst += 4;
    }
  }
Пример #2
0
  void update(double time,
              uint32_t* out,
              const uint32_t* in1,
              const uint32_t* in2,
              const uint32_t* in3)
  {
    uint8_t *dst = reinterpret_cast<uint8_t*>(out);
    const uint8_t *src1 = reinterpret_cast<const uint8_t*>(in1);
    const uint8_t *src2 = reinterpret_cast<const uint8_t*>(in2);
    
    for (int i=0; i<size; ++i)
    {
      uint32_t tmp;
      uint8_t alpha_src1 = src1[3];
      uint8_t alpha_dst;
      uint8_t w1 = src2[3];

      // compute destination alpha
      alpha_dst = dst[3] = INT_MULT(alpha_src1, w1, tmp);

       // compute destination values
      if (alpha_dst == 0)
        for (int b=0; b<3; ++b)
          dst[b] = 0;
      else
        for (int b=0; b<3; ++b)
          dst[b] = CLAMP0255( (uint32_t)( (uint32_t) (INT_MULT(src1[b], alpha_src1, tmp) * w1) / alpha_dst) );
      
      src1 += 4;
      src2 += 4;
      dst += 4;
    }
  }
Пример #3
0
 /**
  *
  * Perform an RGB[A] softlight operation between the pixel sources
  * in1 and in2.
  *
  **/
 void update(double time,
             uint32_t* out,
             const uint32_t* in1,
             const uint32_t* in2)
 {
   const uint8_t *src1 = reinterpret_cast<const uint8_t*>(in1);
   const uint8_t *src2 = reinterpret_cast<const uint8_t*>(in2);
   uint8_t *dst = reinterpret_cast<uint8_t*>(out);
   uint32_t sizeCounter = size;
           
   uint32_t b, tmpS, tmpM, tmp1, tmp2, tmp3;
 
   while (sizeCounter--)
     {
       for (b = 0; b < ALPHA; b++)
         {
           /* Mix multiply and screen */
           tmpM = INT_MULT(src1[b], src2[b], tmpM);
           tmpS = 255 - INT_MULT((255 - src1[b]), (255 - src2[b]), tmp1);
           dst[b] = INT_MULT((255 - src1[b]), tmpM, tmp2) + INT_MULT(src1[b], tmpS, tmp3);
         }
 
       dst[ALPHA] = MIN(src1[ALPHA], src2[ALPHA]);
 
       src1 += NBYTES;
       src2 += NBYTES;
       dst += NBYTES;
     }
 }
Пример #4
0
/////////////////////////////////////////////////////////
// processDualImage
//
/////////////////////////////////////////////////////////
void pix_multiply :: processRGBA_RGBA(imageStruct &image, imageStruct &right)
{
    int datasize = image.xsize * image.ysize;
    unsigned char *leftPix = image.data;
    unsigned char *rightPix = right.data;

    while(datasize--)    {
        leftPix[chRed] = INT_MULT(leftPix[chRed], rightPix[chRed]);
        leftPix[chGreen] = INT_MULT(leftPix[chGreen], rightPix[chGreen]);
        leftPix[chBlue] = INT_MULT(leftPix[chBlue], rightPix[chBlue]);
        leftPix += 4;
        rightPix += 4;
    }
}
Пример #5
0
	Bitmap* SoftGlow::Process2(const Bitmap* src, int radius, float sharpness, float brightness)
	{
		assert(src && src->IsValid());

		Bitmap* dst = new Bitmap(src->Width(), src->Height(), src->biBitCount, 0, false);
		assert(dst);
		//calc sharpness and brightness
		for (int y = 0; y < src->Height(); y++)
		{
			uint8* p0 = src->Get(0, y);
			uint8* p1 = dst->Get(0, y);

			for (int x = 0; x < src->Width(); x++)
			{
				*(p1 + 0) = (uint8)CalcSharpAndBright(*(p0 + 0), sharpness, brightness);
				*(p1 + 1) = (uint8)CalcSharpAndBright(*(p0 + 1), sharpness, brightness);
				*(p1 + 2) = (uint8)CalcSharpAndBright(*(p0 + 2), sharpness, brightness);

				p0 += src->PixelBytes();
				p1 += dst->PixelBytes();
			}
		}
		//gaussion filter
		Gaussion(dst, (float)radius);

#ifdef _DEBUG
		dst->Save("f:\\tmp0.bmp");
#endif
		int temp;
		for (int y = 0; y < src->Height(); y++)
		{
			uint8* p0 = src->Get(0, y);
			uint8* p1 = dst->Get(0, y);

			for (int x = 0; x < src->Width(); x++)
			{
				//screen op
				*(p1 + 0) = 255 - INT_MULT((255 - *(p0 + 0)), (255 - *(p1 + 0)), temp);
				*(p1 + 1) = 255 - INT_MULT((255 - *(p0 + 1)), (255 - *(p1 + 1)), temp);
				*(p1 + 2) = 255 - INT_MULT((255 - *(p0 + 2)), (255 - *(p1 + 2)), temp);

				p0 += src->PixelBytes();
				p1 += dst->PixelBytes();
			}
		}

		return dst;
	}
Пример #6
0
  /**
   *
   * Perform an RGB[A] multiply operation between the pixel sources
   * in1 and in2.
   *
   **/
  void update(double time,
              uint32_t* out,
              const uint32_t* in1,
              const uint32_t* in2,
              const uint32_t* in3)
  {
    const uint8_t *src1 = reinterpret_cast<const uint8_t*>(in1);
    const uint8_t *src2 = reinterpret_cast<const uint8_t*>(in2);
    uint8_t *dst = reinterpret_cast<uint8_t*>(out);
    uint32_t sizeCounter = size;
            
    uint32_t b, tmp;
  
    while (sizeCounter--)
      {
        for (b = 0; b < ALPHA; b++)
          dst[b] = INT_MULT(src1[b], src2[b], tmp);

        dst[ALPHA] = MIN(src1[ALPHA], src2[ALPHA]);

        src1 += NBYTES;
        src2 += NBYTES;
        dst += NBYTES;
      }
  }
Пример #7
0
void alpha_xor(unsigned char *dst,
               const unsigned char *src1,
               const unsigned char *src2,
               unsigned int n)
{
  unsigned int b;
  unsigned int tmp;
  unsigned char w1, w2;
  while (n--)
  {
    w1 = (255 - src2[IDX_RGBA_A]);
    w2 = (255 - src1[IDX_RGBA_A]);
    for (b=0; b<SIZE_RGBA; ++b)
      dst[b] = INT_MULT(src1[b], w1, tmp) + INT_MULT(src2[b], w2, tmp);
    src1+=SIZE_RGBA;
    src2+=SIZE_RGBA;
    dst+=SIZE_RGBA;
  }
}
Пример #8
0
void alpha_premultiply(unsigned char *src,
                       unsigned int n)
{
  unsigned int tmp;
  while (n--)
  {
    for (int i=0; i<SIZE_RGB; ++i)
      src[i] = INT_MULT(src[i], src[IDX_RGBA_A], tmp);
    src += SIZE_RGBA;
  }
}
Пример #9
0
/////////////////////////////////////////////////////////
// processDualGray
//
/////////////////////////////////////////////////////////
void pix_multiply :: processGray_Gray(imageStruct &image, imageStruct &right)
{
    int datasize = image.xsize * image.ysize;
    unsigned char *leftPix = image.data;
    unsigned char *rightPix = right.data;

    while(datasize--)	{
        unsigned int alpha = rightPix[chGray];
        leftPix[chGray] = INT_MULT(leftPix[chGray], alpha);
        leftPix++;
        rightPix++;
    }
}
Пример #10
0
void alpha_in(unsigned char *dst,
              const unsigned char *src1,
              const unsigned char *src2,
              unsigned int n)
{
  unsigned int b;
  unsigned int tmp;
  unsigned char w1;
  while (n--)
  {
    w1 = src2[IDX_RGBA_A];
    for (b=0; b<SIZE_RGBA; ++b)
      dst[b] = INT_MULT(src1[b], w1, tmp);
//     dst[IDX_RGBA_A] = INT_MULT(src1[b], w1, tmp);CLAMP0255( ((int)(src1[IDX_RGBA_A] * w1)) / 255 );
    src1+=SIZE_RGBA;
    src2+=SIZE_RGBA;
    dst+=SIZE_RGBA;
  }
}
Пример #11
0
void RenderEngine::renderLayer(
  const Layer* layer,
  Image *image,
  int source_x, int source_y,
  FrameNumber frame, Zoom zoom,
  void (*zoomed_func)(Image*, const Image*, const Palette*, int, int, int, int, Zoom),
  bool render_background,
  bool render_transparent,
  int blend_mode)
{
  // we can't read from this layer
  if (!layer->isVisible())
    return;

  switch (layer->type()) {

    case ObjectType::LayerImage: {
      if ((!render_background  &&  layer->isBackground()) ||
          (!render_transparent && !layer->isBackground()))
        break;

      const Cel* cel = static_cast<const LayerImage*>(layer)->getCel(frame);
      if (cel != NULL) {
        Image* src_image;

        // Is the 'preview_image' set to be used with this layer?
        if ((selected_layer == layer) &&
            (selected_frame == frame) &&
            (preview_image != NULL)) {
          src_image = preview_image;
        }
        // If not, we use the original cel-image from the images' stock
        else {
          src_image = cel->image();
        }

        if (src_image) {
          int t, output_opacity;

          output_opacity = MID(0, cel->opacity(), 255);
          output_opacity = INT_MULT(output_opacity, global_opacity, t);

          ASSERT(src_image->maskColor() == m_sprite->transparentColor());

          (*zoomed_func)(image, src_image, m_sprite->getPalette(frame),
            zoom.apply(cel->x()) - source_x,
            zoom.apply(cel->y()) - source_y,
            output_opacity,
            (blend_mode < 0 ?
              static_cast<const LayerImage*>(layer)->getBlendMode():
              blend_mode),
            zoom);
        }
      }
      break;
    }

    case ObjectType::LayerFolder: {
      LayerConstIterator it = static_cast<const LayerFolder*>(layer)->getLayerBegin();
      LayerConstIterator end = static_cast<const LayerFolder*>(layer)->getLayerEnd();

      for (; it != end; ++it) {
        renderLayer(*it, image,
          source_x, source_y,
          frame, zoom, zoomed_func,
          render_background,
          render_transparent,
          blend_mode);
      }
      break;
    }

  }

  // Draw extras
  if (m_document->getExtraCel() &&
      layer == m_currentLayer &&
      frame == m_currentFrame) {
    Cel* extraCel = m_document->getExtraCel();
    if (extraCel->opacity() > 0) {
      Image* extraImage = m_document->getExtraCelImage();

      (*zoomed_func)(image, extraImage, m_sprite->getPalette(frame),
        zoom.apply(extraCel->x()) - source_x,
        zoom.apply(extraCel->y()) - source_y,
        extraCel->opacity(),
        m_document->getExtraCelBlendMode(), zoom);
    }
  }
}
Пример #12
0
	Bitmap* SoftGlow::Process1(const Bitmap* src, int radius, float sharpness, float brightness)
	{
		assert(src && src->IsValid());

		int width = src->Width();
		int height = src->Height();

		Bitmap* tmp = new Bitmap(width, height, 8);
		assert(tmp);

		for (int y = 0; y < height; y++)
		{
			uint8* p0 = src->Get(0, y);
			uint8* p1 = tmp->Get(0, y);

			for (int x = 0; x < width; x++)
			{
				uint8 b = *(p0 + 0);
				uint8 g = *(p0 + 1);
				uint8 r = *(p0 + 2);

				*p1 = (uint8)rgb_to_l(r, g, b);

				*p1 = (uint8)CalcSharpAndBright(*p1, sharpness, brightness);

				p0 += src->PixelBytes();
				p1 += tmp->PixelBytes();
			}
		}

		Gaussion(tmp, (float)radius);

#ifdef _DEBUG
		tmp->Save("f:\\tmp0.bmp");
#endif
		Bitmap* dst = new Bitmap(src->Width(), src->Height(), src->biBitCount);
		assert(dst);
		int temp;
		for (int y = 0; y < height; y++)
		{
			uint8* p0 = src->Get(0, y);
			uint8* p1 = tmp->Get(0, y);
			uint8* p2 = dst->Get(0, y);

			for (int x = 0; x < width; x++)
			{
				//screen op
				*(p2 + 0) = 255 - INT_MULT((255 - *(p0 + 0)), (255 - *p1), temp);
				*(p2 + 1) = 255 - INT_MULT((255 - *(p0 + 1)), (255 - *p1), temp);
				*(p2 + 2) = 255 - INT_MULT((255 - *(p0 + 2)), (255 - *p1), temp);

				p0 += src->PixelBytes();
				p1 += tmp->PixelBytes();
				p2 += dst->PixelBytes();
			}
		}

		delete tmp;

		return dst;
	}
Пример #13
0
static void
softglow (GimpDrawable *drawable,
          GimpPreview  *preview)
{
  GimpPixelRgn  src_rgn, dest_rgn;
  GimpPixelRgn *pr;
  gint          width, height;
  gint          bytes;
  gboolean      has_alpha;
  guchar       *dest;
  guchar       *src, *sp_p, *sp_m;
  gdouble       n_p[5], n_m[5];
  gdouble       d_p[5], d_m[5];
  gdouble       bd_p[5], bd_m[5];
  gdouble      *val_p, *val_m, *vp, *vm;
  gint          x1, y1, x2, y2;
  gint          i, j;
  gint          row, col, b;
  gint          terms;
  gint          progress, max_progress;
  gint          initial_p[4];
  gint          initial_m[4];
  gint          tmp;
  gdouble       radius;
  gdouble       std_dev;
  gdouble       val;

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);
      x2 = x1 + width;
      y2 = y1 + height;
    }
  else
    {
      gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
      width     = (x2 - x1);
      height    = (y2 - y1);
    }

  bytes     = drawable->bpp;
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);

  val_p = g_new (gdouble, MAX (width, height));
  val_m = g_new (gdouble, MAX (width, height));

  dest = g_new0 (guchar, width * height);

  progress = 0;
  max_progress = width * height * 3;

  /* Initialize the pixel regions. */
  gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, width, height, FALSE, FALSE);

  for (pr = gimp_pixel_rgns_register (1, &src_rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      guchar *src_ptr  = src_rgn.data;
      guchar *dest_ptr = dest + (src_rgn.y - y1) * width + (src_rgn.x - x1);

      for (row = 0; row < src_rgn.h; row++)
        {
          for (col = 0; col < src_rgn.w; col++)
            {
              /* desaturate */
              if (bytes > 2)
                dest_ptr[col] = (guchar) gimp_rgb_to_l_int (src_ptr[col * bytes + 0],
                                                            src_ptr[col * bytes + 1],
                                                            src_ptr[col * bytes + 2]);
              else
                dest_ptr[col] = (guchar) src_ptr[col * bytes];

              /* compute sigmoidal transfer */
              val = dest_ptr[col] / 255.0;
              val = 255.0 / (1 + exp (-(SIGMOIDAL_BASE + (svals.sharpness * SIGMOIDAL_RANGE)) * (val - 0.5)));
              val = val * svals.brightness;
              dest_ptr[col] = (guchar) CLAMP (val, 0, 255);
            }

          src_ptr  += src_rgn.rowstride;
          dest_ptr += width;
        }

      if (!preview)
        {
          progress += src_rgn.w * src_rgn.h;
          gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
        }
    }

  /*  Calculate the standard deviations  */
  radius  = fabs (svals.glow_radius) + 1.0;
  std_dev = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0)));

  /*  derive the constants for calculating the gaussian from the std dev  */
  find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);

  /*  First the vertical pass  */
  for (col = 0; col < width; col++)
    {
      memset (val_p, 0, height * sizeof (gdouble));
      memset (val_m, 0, height * sizeof (gdouble));

      src  = dest + col;
      sp_p = src;
      sp_m = src + width * (height - 1);
      vp   = val_p;
      vm   = val_m + (height - 1);

      /*  Set up the first vals  */
      initial_p[0] = sp_p[0];
      initial_m[0] = sp_m[0];

      for (row = 0; row < height; row++)
        {
          gdouble *vpptr, *vmptr;

          terms = (row < 4) ? row : 4;

          vpptr = vp; vmptr = vm;
          for (i = 0; i <= terms; i++)
            {
              *vpptr += n_p[i] * sp_p[-i * width] - d_p[i] * vp[-i];
              *vmptr += n_m[i] * sp_m[i * width] - d_m[i] * vm[i];
            }
          for (j = i; j <= 4; j++)
            {
              *vpptr += (n_p[j] - bd_p[j]) * initial_p[0];
              *vmptr += (n_m[j] - bd_m[j]) * initial_m[0];
            }

          sp_p += width;
          sp_m -= width;
          vp ++;
          vm --;
        }

      transfer_pixels (val_p, val_m, dest + col, width, height);

      if (!preview)
        {
          progress += height;
          if ((col % 5) == 0)
            gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
        }
    }

  for (row = 0; row < height; row++)
    {
      memset (val_p, 0, width * sizeof (gdouble));
      memset (val_m, 0, width * sizeof (gdouble));

      src = dest + row * width;

      sp_p = src;
      sp_m = src + width - 1;
      vp = val_p;
      vm = val_m + width - 1;

      /*  Set up the first vals  */
      initial_p[0] = sp_p[0];
      initial_m[0] = sp_m[0];

      for (col = 0; col < width; col++)
        {
          gdouble *vpptr, *vmptr;

          terms = (col < 4) ? col : 4;

          vpptr = vp; vmptr = vm;

          for (i = 0; i <= terms; i++)
            {
              *vpptr += n_p[i] * sp_p[-i] - d_p[i] * vp[-i];
              *vmptr += n_m[i] * sp_m[i] - d_m[i] * vm[i];
            }

          for (j = i; j <= 4; j++)
            {
              *vpptr += (n_p[j] - bd_p[j]) * initial_p[0];
              *vmptr += (n_m[j] - bd_m[j]) * initial_m[0];
            }

          sp_p ++;
          sp_m --;
          vp ++;
          vm --;
        }

      transfer_pixels (val_p, val_m, dest + row * width, 1, width);

      if (!preview)
        {
          progress += width;
          if ((row % 5) == 0)
            gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
        }
    }

  /* Initialize the pixel regions. */
  gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, width, height, FALSE, FALSE);
  gimp_pixel_rgn_init (&dest_rgn, drawable,
                       x1, y1, width, height, (preview == NULL), TRUE);

  for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      guchar *src_ptr  = src_rgn.data;
      guchar *dest_ptr = dest_rgn.data;
      guchar *blur_ptr = dest + (src_rgn.y - y1) * width + (src_rgn.x - x1);

      for (row = 0; row < src_rgn.h; row++)
        {
          for (col = 0; col < src_rgn.w; col++)
            {
              /* screen op */
              for (b = 0; b < (has_alpha ? (bytes - 1) : bytes); b++)
                dest_ptr[col * bytes + b] =
                  255 - INT_MULT((255 - src_ptr[col * bytes + b]),
                                 (255 - blur_ptr[col]), tmp);
              if (has_alpha)
                dest_ptr[col * bytes + b] = src_ptr[col * bytes + b];
            }

          src_ptr  += src_rgn.rowstride;
          dest_ptr += dest_rgn.rowstride;
          blur_ptr += width;
        }

      if (preview)
        {
          gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                             &dest_rgn);
        }
      else
        {
          progress += src_rgn.w * src_rgn.h;
          gimp_progress_update ((gdouble) progress / (gdouble) max_progress);
        }
    }

  if (! preview)
    {
      /*  merge the shadow, update the drawable  */
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id,
                            x1, y1, (x2 - x1), (y2 - y1));
    }

  /*  free up buffers  */
  g_free (val_p);
  g_free (val_m);
  g_free (dest);
}