static void merge_zoomed_image(Image* dst, const Image* src, const Palette* pal, int x, int y, int opacity, int blend_mode, int zoom) { BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blend_mode); typename SrcTraits::address_t src_address; typename DstTraits::address_t dst_address, dst_address_end; typename DstTraits::address_t scanline, scanline_address; int src_x, src_y, src_w, src_h; int dst_x, dst_y, dst_w, dst_h; int box_x, box_y, box_w, box_h; int first_box_w, first_box_h; int line_h, bottom; box_w = 1<<zoom; box_h = 1<<zoom; src_x = 0; src_y = 0; src_w = src->w; src_h = src->h; dst_x = x; dst_y = y; dst_w = src->w<<zoom; dst_h = src->h<<zoom; // clipping... if (dst_x < 0) { src_x += (-dst_x)>>zoom; src_w -= (-dst_x)>>zoom; dst_w -= (-dst_x); first_box_w = box_w - ((-dst_x) % box_w); dst_x = 0; }
static void merge_zoomed_image(Image* dst, const Image* src, const Palette* pal, int x, int y, int opacity, int blend_mode, int zoom) { BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blend_mode); int src_x, src_y, src_w, src_h; int dst_x, dst_y, dst_w, dst_h; int box_x, box_y, box_w, box_h; int first_box_w, first_box_h; int line_h, bottom; box_w = 1<<zoom; box_h = 1<<zoom; src_x = 0; src_y = 0; src_w = src->width(); src_h = src->height(); dst_x = x; dst_y = y; dst_w = src->width()<<zoom; dst_h = src->height()<<zoom; // clipping... if (dst_x < 0) { src_x += (-dst_x)>>zoom; src_w -= (-dst_x)>>zoom; dst_w -= (-dst_x); first_box_w = box_w - ((-dst_x) % box_w); dst_x = 0; }
void SVGPath::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtrWillBeRawPtr<SVGPropertyBase> fromValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toValue, PassRefPtrWillBeRawPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) { ASSERT(animationElement); bool isToAnimation = animationElement->animationMode() == ToAnimation; const RefPtrWillBeRawPtr<SVGPath> from = toSVGPath(fromValue); const RefPtrWillBeRawPtr<SVGPath> to = toSVGPath(toValue); const RefPtrWillBeRawPtr<SVGPath> toAtEndOfDuration = toSVGPath(toAtEndOfDurationValue); const SVGPathByteStream& toStream = to->byteStream(); const SVGPathByteStream* fromStream = &from->byteStream(); OwnPtr<SVGPathByteStream> copy; // If no 'to' value is given, nothing to animate. if (!toStream.size()) return; if (isToAnimation) { copy = byteStream().copy(); fromStream = copy.get(); } // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation. if (fromStream->size() != toStream.size() && fromStream->size()) { if (percentage < 0.5) { if (!isToAnimation) { m_byteStream = fromStream->copy(); return; } } else { m_byteStream = toStream.copy(); return; } } OwnPtr<SVGPathByteStream> lastAnimatedStream = m_byteStream.release(); m_byteStream = SVGPathByteStream::create(); SVGPathByteStreamBuilder builder(*m_byteStream); SVGPathByteStreamSource fromSource(*fromStream); SVGPathByteStreamSource toSource(toStream); SVGPathBlender blender(&fromSource, &toSource, &builder); blender.blendAnimatedPath(percentage); // Handle additive='sum'. if (!fromStream->size() || (animationElement->isAdditive() && !isToAnimation)) addToSVGPathByteStream(*m_byteStream, *lastAnimatedStream); // Handle accumulate='sum'. if (animationElement->isAccumulated() && repeatCount) addToSVGPathByteStream(*m_byteStream, toAtEndOfDuration->byteStream(), repeatCount); }
bool addToSVGPathByteStream(SVGPathByteStream& fromStream, const SVGPathByteStream& byStream, unsigned repeatCount) { if (fromStream.isEmpty() || byStream.isEmpty()) return true; OwnPtr<SVGPathByteStream> fromStreamCopy = fromStream.copy(); fromStream.clear(); SVGPathByteStreamBuilder builder(fromStream); SVGPathByteStreamSource fromSource(*fromStreamCopy); SVGPathByteStreamSource bySource(byStream); SVGPathBlender blender(&fromSource, &bySource, &builder); return blender.addAnimatedPath(repeatCount); }
PassRefPtr<AnimatableValue> AnimatablePath::interpolateTo(const AnimatableValue* value, double fraction) const { if (usesDefaultInterpolationWith(value)) return defaultInterpolateTo(this, value, fraction); std::unique_ptr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); SVGPathByteStreamBuilder builder(*byteStream); SVGPathByteStreamSource fromSource(path()->byteStream()); SVGPathByteStreamSource toSource(toAnimatablePath(value)->path()->byteStream()); SVGPathBlender blender(&fromSource, &toSource, &builder); bool ok = blender.blendAnimatedPath(fraction); ASSERT_UNUSED(ok, ok); return AnimatablePath::create(StylePath::create(std::move(byteStream))); }
int main(void) { setvbuf(stdout, NULL, _IONBF, 0); FILE *input_file1 = fopen("in1.bmp", "rb"); FILE *input_file2 = fopen("in2.bmp", "rb"); FILE *blend = fopen("blend.bmp", "wb"); FILE *checker = fopen("checker.bmp", "wb"); char headerA_1[2], headerA_2[12], headerA_3[8], headerA_4[16]; char headerB_1[2], headerB_2[12], headerB_3[8], headerB_4[16]; int width1 = 0, height1 = 0, width2 = 0, height2 = 0; int file_size1 = 0, file_size2 = 0, image_size1 = 0, image_size2 = 0; readInputFile(input_file1, headerA_1, headerA_2, headerA_3, headerA_4, &file_size1, &image_size1, &width1, &height1); readInputFile(input_file2, headerB_1, headerB_2, headerB_3, headerB_4, &file_size2, &image_size2, &width2, &height2); unsigned char pixels1[height1][width1 * 3], pixels2[height2][width2 * 3]; unsigned char checkerData[height1][width1 * 3]; unsigned char blendData[height1][width1 * 3]; readPixels(input_file1, &width1, &height1, pixels1); readPixels(input_file2, &width2, &height2, pixels2); blender(&width1, &height1, pixels1, pixels2, blendData); transformCheckerBoard(&width1, &height1, pixels1, pixels2, checkerData); printOutput(blend, headerA_1, headerA_2, headerA_3, headerA_4, &file_size1, &image_size1, &width1, &height1, blendData); printOutput(checker, headerB_1, headerB_2, headerB_3, headerB_4, &file_size2, &image_size2, &width2, &height2, checkerData); fclose(blend); fclose(checker); return 0; }
static void merge_zoomed_image_scale_down(Image* dst, const Image* src, const Palette* pal, int x, int y, int opacity, int blend_mode, Zoom zoom) { BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blend_mode); int src_x, src_y, src_w, src_h; int dst_x, dst_y, dst_w, dst_h; int unbox_w, unbox_h; int bottom; unbox_w = zoom.remove(1); unbox_h = zoom.remove(1); src_x = 0; src_y = 0; src_w = src->width(); src_h = src->height(); dst_x = x; dst_y = y; dst_w = zoom.apply(src->width()); dst_h = zoom.apply(src->height()); // clipping... if (dst_x < 0) { src_x += zoom.remove(-dst_x); src_w -= zoom.remove(-dst_x); dst_w -= (-dst_x); dst_x = 0; } if (dst_y < 0) { src_y += zoom.remove(-dst_y); src_h -= zoom.remove(-dst_y); dst_h -= (-dst_y); dst_y = 0; } if (dst_x+dst_w > dst->width()) { src_w -= zoom.remove(dst_x+dst_w-dst->width()); dst_w = dst->width() - dst_x; } if (dst_y+dst_h > dst->height()) { src_h -= zoom.remove(dst_y+dst_h-dst->height()); dst_h = dst->height() - dst_y; } src_w = zoom.remove(zoom.apply(src_w)); src_h = zoom.remove(zoom.apply(src_h)); if ((src_w <= 0) || (src_h <= 0) || (dst_w <= 0) || (dst_h <= 0)) return; bottom = dst_y+dst_h-1; // Lock all necessary bits const LockImageBits<SrcTraits> srcBits(src, gfx::Rect(src_x, src_y, src_w, src_h)); LockImageBits<DstTraits> dstBits(dst, gfx::Rect(dst_x, dst_y, dst_w, dst_h)); typename LockImageBits<SrcTraits>::const_iterator src_it = srcBits.begin(); typename LockImageBits<SrcTraits>::const_iterator src_end = srcBits.end(); typename LockImageBits<DstTraits>::iterator dst_it, dst_end; // For each line to draw of the source image... for (y=0; y<src_h; y+=unbox_h) { dst_it = dstBits.begin_area(gfx::Rect(dst_x, dst_y, dst_w, 1)); dst_end = dstBits.end_area(gfx::Rect(dst_x, dst_y, dst_w, 1)); for (x=0; x<src_w; x+=unbox_w) { ASSERT(src_it >= srcBits.begin() && src_it < src_end); ASSERT(dst_it >= dstBits.begin() && dst_it < dst_end); blender(*dst_it, *dst_it, *src_it, opacity); // Skip source pixels for (int delta=0; delta < unbox_w && src_it != src_end; ++delta) ++src_it; ++dst_it; } if (++dst_y > bottom) break; // Skip lines for (int delta=0; delta < src_w * (unbox_h-1) && src_it != src_end; ++delta) ++src_it; } }
static void merge_zoomed_image_scale_up(Image* dst, const Image* src, const Palette* pal, int x, int y, int opacity, int blend_mode, Zoom zoom) { BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blend_mode); int src_x, src_y, src_w, src_h; int dst_x, dst_y, dst_w, dst_h; int box_x, box_y, box_w, box_h; int first_box_w, first_box_h; int line_h, bottom; box_w = zoom.apply(1); box_h = zoom.apply(1); src_x = 0; src_y = 0; src_w = src->width(); src_h = src->height(); dst_x = x; dst_y = y; dst_w = zoom.apply(src->width()); dst_h = zoom.apply(src->height()); // clipping... if (dst_x < 0) { src_x += zoom.remove(-dst_x); src_w -= zoom.remove(-dst_x); dst_w -= (-dst_x); first_box_w = box_w - ((-dst_x) % box_w); dst_x = 0; } else first_box_w = 0; if (dst_y < 0) { src_y += zoom.remove(-dst_y); src_h -= zoom.remove(-dst_y); dst_h -= (-dst_y); first_box_h = box_h - ((-dst_y) % box_h); dst_y = 0; } else first_box_h = 0; if (dst_x+dst_w > dst->width()) { src_w -= zoom.remove(dst_x+dst_w-dst->width()); dst_w = dst->width() - dst_x; } if (dst_y+dst_h > dst->height()) { src_h -= zoom.remove(dst_y+dst_h-dst->height()); dst_h = dst->height() - dst_y; } if ((src_w <= 0) || (src_h <= 0) || (dst_w <= 0) || (dst_h <= 0)) return; bottom = dst_y+dst_h-1; // the scanline variable is used to blend src/dst pixels one time for each pixel typedef std::vector<typename DstTraits::pixel_t> Scanline; Scanline scanline(src_w); typename Scanline::iterator scanline_it; #ifdef _DEBUG typename Scanline::iterator scanline_end = scanline.end(); #endif // Lock all necessary bits const LockImageBits<SrcTraits> srcBits(src, gfx::Rect(src_x, src_y, src_w, src_h)); LockImageBits<DstTraits> dstBits(dst, gfx::Rect(dst_x, dst_y, dst_w, dst_h)); typename LockImageBits<SrcTraits>::const_iterator src_it = srcBits.begin(); #ifdef _DEBUG typename LockImageBits<SrcTraits>::const_iterator src_end = srcBits.end(); #endif typename LockImageBits<DstTraits>::iterator dst_it, dst_end; // For each line to draw of the source image... for (y=0; y<src_h; ++y) { dst_it = dstBits.begin_area(gfx::Rect(dst_x, dst_y, dst_w, 1)); dst_end = dstBits.end_area(gfx::Rect(dst_x, dst_y, dst_w, 1)); // Read 'src' and 'dst' and blend them, put the result in `scanline' scanline_it = scanline.begin(); for (x=0; x<src_w; ++x) { ASSERT(src_it >= srcBits.begin() && src_it < src_end); ASSERT(dst_it >= dstBits.begin() && dst_it < dst_end); ASSERT(scanline_it >= scanline.begin() && scanline_it < scanline_end); blender(*scanline_it, *dst_it, *src_it, opacity); ++src_it; int delta; if ((x == 0) && (first_box_w > 0)) delta = first_box_w; else delta = box_w; while (dst_it != dst_end && delta-- > 0) ++dst_it; ++scanline_it; } // Get the 'height' of the line to be painted in 'dst' if ((y == 0) && (first_box_h > 0)) line_h = first_box_h; else line_h = box_h; // Draw the line in 'dst' for (box_y=0; box_y<line_h; ++box_y) { dst_it = dstBits.begin_area(gfx::Rect(dst_x, dst_y, dst_w, 1)); dst_end = dstBits.end_area(gfx::Rect(dst_x, dst_y, dst_w, 1)); scanline_it = scanline.begin(); x = 0; // first pixel if (first_box_w > 0) { for (box_x=0; box_x<first_box_w; ++box_x) { ASSERT(scanline_it != scanline_end); ASSERT(dst_it != dst_end); *dst_it = *scanline_it; ++dst_it; if (dst_it == dst_end) goto done_with_line; } ++scanline_it; ++x; } // the rest of the line for (; x<src_w; ++x) { for (box_x=0; box_x<box_w; ++box_x) { ASSERT(dst_it != dst_end); *dst_it = *scanline_it; ++dst_it; if (dst_it == dst_end) goto done_with_line; } ++scanline_it; } done_with_line:; if (++dst_y > bottom) goto done_with_blit; } // go to the next line in the source image ++src_y; } done_with_blit:; }