Пример #1
0
void ReplaceColorFilter::applyToGrayscale(FilterManager* filterMgr)
{
  const uint16_t* src_address = (uint16_t*)filterMgr->getSourceAddress();
  uint16_t* dst_address = (uint16_t*)filterMgr->getDestinationAddress();
  int w = filterMgr->getWidth();
  int src_k, src_a;
  int dst_k, dst_a;
  int x, c;

  dst_k = _graya_getv(m_from);
  dst_a = _graya_geta(m_from);

  for (x=0; x<w; x++) {
    if (filterMgr->skipPixel()) {
      ++src_address;
      ++dst_address;
      continue;
    }

    c = *(src_address++);

    src_k = _graya_getv(c);
    src_a = _graya_geta(c);

    if ((ABS(src_k-dst_k) <= m_tolerance) &&
        (ABS(src_a-dst_a) <= m_tolerance))
      *(dst_address++) = m_to;
    else
      *(dst_address++) = c;
  }
}
Пример #2
0
static bool is_same_pixel(PixelFormat pixelFormat, int pixel1, int pixel2)
{
  switch (pixelFormat) {
    case IMAGE_RGB:
      if (_rgba_geta(pixel1) == 0 && _rgba_geta(pixel2) == 0)
        return true;
      break;
    case IMAGE_GRAYSCALE:
      if (_graya_geta(pixel1) == 0 && _graya_geta(pixel2) == 0)
        return true;
      break;
  }
  return pixel1 == pixel2;
}
Пример #3
0
// static
Color Color::fromImage(PixelFormat pixelFormat, int c)
{
  Color color = Color::fromMask();

  switch (pixelFormat) {

    case IMAGE_RGB:
      if (_rgba_geta(c) > 0) {
        color = Color::fromRgb(_rgba_getr(c),
                               _rgba_getg(c),
                               _rgba_getb(c));
      }
      break;

    case IMAGE_GRAYSCALE:
      if (_graya_geta(c) > 0) {
        color = Color::fromGray(_graya_getv(c));
      }
      break;

    case IMAGE_INDEXED:
      color = Color::fromIndex(c);
      break;
  }

  return color;
}
Пример #4
0
void InvertColorFilter::applyToGrayscale(FilterManager* filterMgr)
{
    const uint16_t* src_address = (uint16_t*)filterMgr->getSourceAddress();
    uint16_t* dst_address = (uint16_t*)filterMgr->getDestinationAddress();
    int w = filterMgr->getWidth();
    Target target = filterMgr->getTarget();
    int x, c, k, a;

    for (x=0; x<w; x++) {
        if (filterMgr->skipPixel()) {
            ++src_address;
            ++dst_address;
            continue;
        }

        c = *(src_address++);

        k = _graya_getv(c);
        a = _graya_geta(c);

        if (target & TARGET_GRAY_CHANNEL) k ^= 0xff;
        if (target & TARGET_ALPHA_CHANNEL) a ^= 0xff;

        *(dst_address++) = _graya(k, a);
    }
}
Пример #5
0
static inline bool color_equal_16(uint16_t c1, uint16_t c2, int tolerance)
{
  if (tolerance == 0)
    return (c1 == c2) || (_graya_geta(c1) == 0 && _graya_geta(c2) == 0);
  else {
    int k1 = _graya_getv(c1);
    int a1 = _graya_geta(c1);
    int k2 = _graya_getv(c2);
    int a2 = _graya_geta(c2);

    if (a1 == 0 && a2 == 0)
      return true;

    return ((ABS(k1-k2) <= tolerance) &&
            (ABS(a1-a2) <= tolerance));
  }
}
Пример #6
0
 void write_scanline(GrayscaleTraits::address_t address, int w, uint8_t* buffer)
 {
   for (int x=0; x<w; ++x) {
     *(buffer++) = _graya_getv(*address);
     *(buffer++) = _graya_geta(*address);
     ++address;
   }
 }
Пример #7
0
 inline void operator()(RgbTraits::address_t& scanline_address,
                        RgbTraits::address_t& dst_address,
                        GrayscaleTraits::address_t& src_address,
                        int opacity)
 {
   if (*src_address != m_mask_color) {
     int v = _graya_getv(*src_address);
     *scanline_address = (*m_blend_color)(*dst_address, _rgba(v, v, v, _graya_geta(*src_address)), opacity);
   }
   else
     *scanline_address = *dst_address;
 }
Пример #8
0
void ConvolutionMatrixFilter::applyToGrayscale(FilterManager* filterMgr)
{
  if (!m_matrix)
    return;

  const Image* src = filterMgr->getSourceImage();
  uint16_t* dst_address = (uint16_t*)filterMgr->getDestinationAddress();
  Target target = filterMgr->getTarget();
  uint16_t color;
  GetPixelsDelegateGrayscale delegate;
  int x = filterMgr->getX();
  int x2 = x+filterMgr->getWidth();
  int y = filterMgr->getY();

  for (; x<x2; ++x) {
    // Avoid the non-selected region
    if (filterMgr->skipPixel()) {
      ++dst_address;
      continue;
    }

    delegate.reset(m_matrix);
    get_neighboring_pixels<GrayscaleTraits>(src, x, y,
                                            m_matrix->getWidth(),
                                            m_matrix->getHeight(),
                                            m_matrix->getCenterX(),
                                            m_matrix->getCenterY(),
                                            m_tiledMode, delegate);

    color = image_getpixel_fast<GrayscaleTraits>(src, x, y);
    if (delegate.div == 0) {
      *(dst_address++) = color;
      continue;
    }

    if (target & TARGET_GRAY_CHANNEL) {
      delegate.v = delegate.v / delegate.div + m_matrix->getBias();
      delegate.v = MID(0, delegate.v, 255);
    }
    else
      delegate.v = _graya_getv(color);

    if (target & TARGET_ALPHA_CHANNEL) {
      delegate.a = delegate.a / m_matrix->getDiv() + m_matrix->getBias();
      delegate.a = MID(0, delegate.a, 255);
    }
    else
      delegate.a = _graya_geta(color);

    *(dst_address++) = _graya(delegate.v, delegate.a);
  }
}
Пример #9
0
void MedianFilter::applyToGrayscale(FilterManager* filterMgr)
{
  const Image* src = filterMgr->getSourceImage();
  uint16_t* dst_address = (uint16_t*)filterMgr->getDestinationAddress();
  Target target = filterMgr->getTarget();
  int color, k, a;
  GetPixelsDelegateGrayscale delegate(m_channel);
  int x = filterMgr->getX();
  int x2 = x+filterMgr->getWidth();
  int y = filterMgr->getY();

  for (; x<x2; ++x) {
    // Avoid the non-selected region
    if (filterMgr->skipPixel()) {
      ++dst_address;
      continue;
    }

    delegate.reset();
    get_neighboring_pixels<GrayscaleTraits>(src, x, y, m_width, m_height, m_width/2, m_height/2,
                                            m_tiledMode, delegate);

    color = image_getpixel_fast<GrayscaleTraits>(src, x, y);

    if (target & TARGET_GRAY_CHANNEL) {
      std::sort(m_channel[0].begin(), m_channel[0].end());
      k = m_channel[0][m_ncolors/2];
    }
    else
      k = _graya_getv(color);

    if (target & TARGET_ALPHA_CHANNEL) {
      std::sort(m_channel[1].begin(), m_channel[1].end());
      a = m_channel[1][m_ncolors/2];
    }
    else
      a = _graya_geta(color);

    *(dst_address++) = _graya(k, a);
  }
}
Пример #10
0
bool StandbyState::onUpdateStatusBar(Editor* editor)
{
  tools::Tool* current_tool = editor->getCurrentEditorTool();
  Sprite* sprite = editor->getSprite();
  int x, y;

  editor->screenToEditor(jmouse_x(0), jmouse_y(0), &x, &y);

  if (!sprite) {
    app_get_statusbar()->clearText();
  }
  // For eye-dropper
  else if (current_tool->getInk(0)->isEyedropper()) {
    int imgtype = sprite->getImgType();
    uint32_t pixel = sprite->getPixel(x, y);
    Color color = Color::fromImage(imgtype, pixel);

    int alpha = 255;
    switch (imgtype) {
      case IMAGE_RGB: alpha = _rgba_geta(pixel); break;
      case IMAGE_GRAYSCALE: alpha = _graya_geta(pixel); break;
    }

    char buf[256];
    usprintf(buf, "- Pos %d %d", x, y);

    app_get_statusbar()->showColor(0, buf, color, alpha);
  }
  else {
    Mask* mask = editor->getDocument()->getMask();

    app_get_statusbar()->setStatusText
      (0, "Pos %d %d, Size %d %d, Frame %d",
       x, y,
       ((mask && mask->bitmap)? mask->w: sprite->getWidth()),
       ((mask && mask->bitmap)? mask->h: sprite->getHeight()),
       sprite->getCurrentFrame()+1);
  }

  return true;
}
Пример #11
0
/**
 * Resizes the source image @a src to the destination image @a dst.
 *
 * @warning If you are using the RESIZE_METHOD_BILINEAR, it is
 * recommended to use @ref image_fixup_transparent_colors function
 * over the source image @a src before using this routine.
 */
void image_resize(const Image* src, Image* dst, ResizeMethod method, const Palette* pal, const RgbMap* rgbmap)
{
  switch (method) {

    // TODO optimize this
    case RESIZE_METHOD_NEAREST_NEIGHBOR: {
      uint32_t color;
      double u, v, du, dv;
      int x, y;

      u = v = 0.0;
      du = src->w * 1.0 / dst->w;
      dv = src->h * 1.0 / dst->h;
      for (y=0; y<dst->h; ++y) {
        for (x=0; x<dst->w; ++x) {
          color = src->getpixel(MID(0, u, src->w-1),
                                MID(0, v, src->h-1));
          dst->putpixel(x, y, color);
          u += du;
        }
        u = 0.0;
        v += dv;
      }
      break;
    }

    // TODO optimize this
    case RESIZE_METHOD_BILINEAR: {
      uint32_t color[4], dst_color = 0;
      double u, v, du, dv;
      int u_floor, u_floor2;
      int v_floor, v_floor2;
      int x, y;

      u = v = 0.0;
      du = (src->w-1) * 1.0 / (dst->w-1);
      dv = (src->h-1) * 1.0 / (dst->h-1);
      for (y=0; y<dst->h; ++y) {
        for (x=0; x<dst->w; ++x) {
          u_floor = floor(u);
          v_floor = floor(v);

          if (u_floor > src->w-1) {
            u_floor = src->w-1;
            u_floor2 = src->w-1;
          }
          else if (u_floor == src->w-1)
            u_floor2 = u_floor;
          else
            u_floor2 = u_floor+1;

          if (v_floor > src->h-1) {
            v_floor = src->h-1;
            v_floor2 = src->h-1;
          }
          else if (v_floor == src->h-1)
            v_floor2 = v_floor;
          else
            v_floor2 = v_floor+1;

          // get the four colors
          color[0] = src->getpixel(u_floor,  v_floor);
          color[1] = src->getpixel(u_floor2, v_floor);
          color[2] = src->getpixel(u_floor,  v_floor2);
          color[3] = src->getpixel(u_floor2, v_floor2);

          // calculate the interpolated color
          double u1 = u - u_floor;
          double v1 = v - v_floor;
          double u2 = 1 - u1;
          double v2 = 1 - v1;

          switch (dst->getPixelFormat()) {
            case IMAGE_RGB: {
              int r = ((_rgba_getr(color[0])*u2 + _rgba_getr(color[1])*u1)*v2 +
                       (_rgba_getr(color[2])*u2 + _rgba_getr(color[3])*u1)*v1);
              int g = ((_rgba_getg(color[0])*u2 + _rgba_getg(color[1])*u1)*v2 +
                       (_rgba_getg(color[2])*u2 + _rgba_getg(color[3])*u1)*v1);
              int b = ((_rgba_getb(color[0])*u2 + _rgba_getb(color[1])*u1)*v2 +
                       (_rgba_getb(color[2])*u2 + _rgba_getb(color[3])*u1)*v1);
              int a = ((_rgba_geta(color[0])*u2 + _rgba_geta(color[1])*u1)*v2 +
                       (_rgba_geta(color[2])*u2 + _rgba_geta(color[3])*u1)*v1);
              dst_color = _rgba(r, g, b, a);
              break;
            }
            case IMAGE_GRAYSCALE: {
              int v = ((_graya_getv(color[0])*u2 + _graya_getv(color[1])*u1)*v2 +
                       (_graya_getv(color[2])*u2 + _graya_getv(color[3])*u1)*v1);
              int a = ((_graya_geta(color[0])*u2 + _graya_geta(color[1])*u1)*v2 +
                       (_graya_geta(color[2])*u2 + _graya_geta(color[3])*u1)*v1);
              dst_color = _graya(v, a);
              break;
            }
            case IMAGE_INDEXED: {
              int r = ((_rgba_getr(pal->getEntry(color[0]))*u2 + _rgba_getr(pal->getEntry(color[1]))*u1)*v2 +
                       (_rgba_getr(pal->getEntry(color[2]))*u2 + _rgba_getr(pal->getEntry(color[3]))*u1)*v1);
              int g = ((_rgba_getg(pal->getEntry(color[0]))*u2 + _rgba_getg(pal->getEntry(color[1]))*u1)*v2 +
                       (_rgba_getg(pal->getEntry(color[2]))*u2 + _rgba_getg(pal->getEntry(color[3]))*u1)*v1);
              int b = ((_rgba_getb(pal->getEntry(color[0]))*u2 + _rgba_getb(pal->getEntry(color[1]))*u1)*v2 +
                       (_rgba_getb(pal->getEntry(color[2]))*u2 + _rgba_getb(pal->getEntry(color[3]))*u1)*v1);
              int a = (((color[0] == 0 ? 0: 255)*u2 + (color[1] == 0 ? 0: 255)*u1)*v2 +
                       ((color[2] == 0 ? 0: 255)*u2 + (color[3] == 0 ? 0: 255)*u1)*v1);
              dst_color = a > 127 ? rgbmap->mapColor(r, g, b): 0;
              break;
            }
            case IMAGE_BITMAP: {
              int g = ((255*color[0]*u2 + 255*color[1]*u1)*v2 +
                       (255*color[2]*u2 + 255*color[3]*u1)*v1);
              dst_color = g > 127 ? 1: 0;
              break;
            }
          }

          dst->putpixel(x, y, dst_color);
          u += du;
        }
        u = 0.0;
        v += dv;
      }
      break;
    }

  }
}
Пример #12
0
/**
 * This routine does not modify the image to the human eye, but
 * internally tries to fixup all colors that are completelly
 * transparent (alpha = 0) with the average of its 4-neighbors.
 */
void image_fixup_transparent_colors(Image* image)
{
  int x, y, u, v;

  switch (image->getPixelFormat()) {

    case IMAGE_RGB: {
      uint32_t c;
      int r, g, b, count;

      for (y=0; y<image->h; ++y) {
        for (x=0; x<image->w; ++x) {
          c = image_getpixel_fast<RgbTraits>(image, x, y);

          // if this is a completelly-transparent pixel...
          if (_rgba_geta(c) == 0) {
            count = 0;
            r = g = b = 0;

            for (v=y-1; v<=y+1; ++v) {
              for (u=x-1; u<=x+1; ++u) {
                if ((u >= 0) && (v >= 0) && (u < image->w) && (v < image->h)) {
                  c = image_getpixel_fast<RgbTraits>(image, u, v);
                  if (_rgba_geta(c) > 0) {
                    r += _rgba_getr(c);
                    g += _rgba_getg(c);
                    b += _rgba_getb(c);
                    ++count;
                  }
                }
              }
            }

            if (count > 0) {
              r /= count;
              g /= count;
              b /= count;
              image_putpixel_fast<RgbTraits>(image, x, y, _rgba(r, g, b, 0));
            }
          }
        }
      }
      break;
    }

    case IMAGE_GRAYSCALE: {
      uint16_t c;
      int k, count;

      for (y=0; y<image->h; ++y) {
        for (x=0; x<image->w; ++x) {
          c = image_getpixel_fast<GrayscaleTraits>(image, x, y);

          // if this is a completelly-transparent pixel...
          if (_graya_geta(c) == 0) {
            count = 0;
            k = 0;

            for (v=y-1; v<=y+1; ++v) {
              for (u=x-1; u<=x+1; ++u) {
                if ((u >= 0) && (v >= 0) && (u < image->w) && (v < image->h)) {
                  c = image_getpixel_fast<GrayscaleTraits>(image, u, v);
                  if (_graya_geta(c) > 0) {
                    k += _graya_getv(c);
                    ++count;
                  }
                }
              }
            }

            if (count > 0) {
              k /= count;
              image_putpixel_fast<GrayscaleTraits>(image, x, y, _graya(k, 0));
            }
          }
        }
      }
      break;
    }

  }
}
Пример #13
0
 void write_pixel(FILE* f, GrayscaleTraits::pixel_t c) {
   fputc(_graya_getv(c), f);
   fputc(_graya_geta(c), f);
 }