Example #1
0
// adapted from http://cpansearch.perl.org/src/RJRAY/Image-Size-3.230/lib/Image/Size.pm
Size BitmapSizeFromData(const char *data, size_t len)
{
    Size result;
    ByteReader r(data, len);
    switch (GfxFormatFromData(data, len)) {
    case Img_BMP:
        if (len >= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)) {
            BITMAPINFOHEADER bmi;
            bool ok = r.UnpackLE(&bmi, sizeof(bmi), "3d2w6d", sizeof(BITMAPFILEHEADER));
            CrashIf(!ok);
            result.Width = bmi.biWidth;
            result.Height = bmi.biHeight;
        }
        break;
    case Img_GIF:
        if (len >= 13) {
            // find the first image's actual size instead of using the
            // "logical screen" size which is sometimes too large
            size_t ix = 13;
            // skip the global color table
            if ((r.Byte(10) & 0x80))
                ix += 3 * (1 << ((r.Byte(10) & 0x07) + 1));
            while (ix + 8 < len) {
                if (r.Byte(ix) == 0x2C) {
                    result.Width = r.WordLE(ix + 5);
                    result.Height = r.WordLE(ix + 7);
                    break;
                }
                else if (r.Byte(ix) == 0x21 && r.Byte(ix + 1) == 0xF9)
                    ix += 8;
                else if (r.Byte(ix) == 0x21 && r.Byte(ix + 1) == 0xFE) {
                    const char *commentEnd = r.Find(ix + 2, 0x00);
                    ix = commentEnd ? commentEnd - data + 1 : len;
                }
                else if (r.Byte(ix) == 0x21 && r.Byte(ix + 1) == 0x01 && ix + 15 < len) {
                    const char *textDataEnd = r.Find(ix + 15, 0x00);
                    ix = textDataEnd ? textDataEnd - data + 1 : len;
                }
                else if (r.Byte(ix) == 0x21 && r.Byte(ix + 1) == 0xFF && ix + 14 < len) {
                    const char *applicationDataEnd = r.Find(ix + 14, 0x00);
                    ix = applicationDataEnd ? applicationDataEnd - data + 1 : len;
                }
                else
                    break;
            }
        }
        break;
    case Img_JPEG:
        // find the last start of frame marker for non-differential Huffman/arithmetic coding
        for (size_t ix = 2; ix + 9 < len && r.Byte(ix) == 0xFF; ) {
            if (0xC0 <= r.Byte(ix + 1) && r.Byte(ix + 1) <= 0xC3 ||
                0xC9 <= r.Byte(ix + 1) && r.Byte(ix + 1) <= 0xCB) {
                result.Width = r.WordBE(ix + 7);
                result.Height = r.WordBE(ix + 5);
            }
            ix += r.WordBE(ix + 2) + 2;
        }
        break;
    case Img_JXR:
    case Img_TIFF:
        if (len >= 10) {
            bool isBE = r.Byte(0) == 'M', isJXR = r.Byte(2) == 0xBC;
            CrashIf(!isBE && r.Byte(0) != 'I' || isJXR && isBE);
            const WORD WIDTH = isJXR ? 0xBC80 : 0x0100, HEIGHT = isJXR ? 0xBC81 : 0x0101;
            size_t idx = r.DWord(4, isBE);
            WORD count = idx <= len - 2 ? r.Word(idx, isBE) : 0;
            for (idx += 2; count > 0 && idx <= len - 12; count--, idx += 12) {
                WORD tag = r.Word(idx, isBE), type = r.Word(idx + 2, isBE);
                if (r.DWord(idx + 4, isBE) != 1)
                    continue;
                else if (WIDTH == tag && 4 == type)
                    result.Width = r.DWord(idx + 8, isBE);
                else if (WIDTH == tag && 3 == type)
                    result.Width = r.Word(idx + 8, isBE);
                else if (WIDTH == tag && 1 == type)
                    result.Width = r.Byte(idx + 8);
                else if (HEIGHT == tag && 4 == type)
                    result.Height = r.DWord(idx + 8, isBE);
                else if (HEIGHT == tag && 3 == type)
                    result.Height = r.Word(idx + 8, isBE);
                else if (HEIGHT == tag && 1 == type)
                    result.Height = r.Byte(idx + 8);
            }
        }
        break;
    case Img_PNG:
        if (len >= 24 && str::StartsWith(data + 12, "IHDR")) {
            result.Width = r.DWordBE(16);
            result.Height = r.DWordBE(20);
        }
        break;
    case Img_TGA:
        if (len >= 16) {
            result.Width = r.WordLE(12);
            result.Height = r.WordLE(14);
        }
        break;
    case Img_WebP:
        if (len >= 30 && str::StartsWith(data + 12, "VP8 ")) {
            result.Width = r.WordLE(26) & 0x3fff;
            result.Height = r.WordLE(28) & 0x3fff;
        }
        else {
            result = webp::SizeFromData(data, len);
        }
        break;
    case Img_JP2:
        if (len >= 32) {
            size_t ix = 0;
            while (ix < len - 32) {
                uint32_t lbox = r.DWordBE(ix);
                uint32_t tbox = r.DWordBE(ix + 4);
                if (0x6A703268 /* jp2h */ == tbox) {
                    ix += 8;
                    if (r.DWordBE(ix) == 24 && r.DWordBE(ix + 4) == 0x69686472 /* ihdr */) {
                        result.Width = r.DWordBE(ix + 16);
                        result.Height = r.DWordBE(ix + 12);
                    }
                    break;
                }
                else if (lbox != 0 && ix < UINT32_MAX - lbox) {
                    ix += lbox;
                }
                else {
                    break;
                }
            }
        }
        break;
    }

    if (result.Empty()) {
        // let GDI+ extract the image size if we've failed
        // (currently happens for animated GIF)
        Bitmap *bmp = BitmapFromData(data, len);
        if (bmp)
            result = Size(bmp->GetWidth(), bmp->GetHeight());
        delete bmp;
    }

    return result;
}
Example #2
0
	void jointColorDepthFillOcclusion_(const Mat& src, const Mat& guide, Mat& dest, const Size ksize, T threshold)
	{
		if (dest.empty())dest.create(src.size(), src.type());
		Mat sim, gim;
		const int radiusw = ksize.width / 2;
		const int radiush = ksize.height / 2;;
		copyMakeBorder(src, sim, radiush, radiush, radiusw, radiusw, cv::BORDER_DEFAULT);
		copyMakeBorder(guide, gim, radiush, radiush, radiusw, radiusw, cv::BORDER_DEFAULT);

		vector<int> _space_ofs_before(ksize.area());
		int* space_ofs_before = &_space_ofs_before[0];

		int maxk = 0;
		for (int i = -radiush; i <= radiush; i++)
		{
			for (int j = -radiusw; j <= radiusw; j++)
			{
				double r = std::sqrt((double)i*i + (double)j*j);
				if (r > radiusw)
					continue;

				space_ofs_before[maxk++] = (int)(i*sim.cols + j);
			}
		}
		const int steps = sim.cols;
		const int step = dest.cols;

		T* sptr = sim.ptr<T>(radiush); sptr += radiusw;
		uchar* jptr = gim.ptr<uchar>(radiush); jptr += radiusw;

		T* dst = dest.ptr<T>(0);

		T th2 = threshold*threshold;
		for (int i = 0; i < src.rows; i++)
		{
			for (int j = 0; j < src.cols; j++)
			{
				const T val0j = jptr[j];

				int minv = INT_MAX;
				T mind = 0;
				if (sptr[j] == 0)
				{
					for (int k = 0; k < maxk; k++)
					{
						if (sptr[j + space_ofs_before[k]] == 0) continue;

						const T valj = jptr[j + space_ofs_before[k]];
						int ab = (int)((valj - val0j)*(valj - val0j));
						if (ab < minv)
						{
							minv = ab;
							mind = sptr[j + space_ofs_before[k]];
						}
					}
					if (minv < th2)
					{
						dst[j] = mind;
					}
				}
			}
			sptr += steps;
			jptr += steps;
			dst += step;
		}
	}
static void CompressTextureSet(
    Vector<VirtFS::VirtDesc>&            files,
    Pair<CString, ImageProcessor> const& file,
    FileProcessor*                       cooker,
    TerminalCursor&                      cursor)
{
    Resource r(MkUrl(file.first.c_str()));

    auto outName = Path(file.first).removeExt();

    PixCmp cmp = PixCmp::RGBA;
    BitFmt bfmt;
    Bytes  data;
    Size   size;

    auto decoder = image_decoders.find(file.second);

    if(decoder == image_decoders.end())
        return;

    if(!decoder->second(cooker, file, cmp, bfmt, size, data, r))
        return;

    if(size.area() == 0)
    {
        return;
    }

    texture_settings_t settings;

    settings.flags    = stb::ImageHint::Undefined;
    settings.max_size = max_texture_size;
    settings.min_size = min_texture_size;
    settings.channels = 4;
    settings.formats  = Compress_ALL; /*!< Use all formats by default */

    settings.parse(outName);

    if(size.w < settings.max_size && size.h < settings.max_size)
    {
        std::tie(data, size) = ScaleImage(
            std::move(data), size, settings.max_size, settings.flags);
    } else if(size.w > settings.max_size && size.h > settings.max_size)
    {
        std::tie(data, size) = ScaleImage(
            std::move(data), size, settings.max_size, settings.flags);
    }

    common_tools_t tools = {cooker, cursor, settings, files};

    if(settings.formats & Compress_DXT)
        CompressDXT(tools, file, size, data, outName);

#if defined(HAVE_ETC2COMP)
    if(settings.formats & Compress_ETC)
        CompressETC12(tools, size, data, outName);
#endif

    if(settings.formats & Compress_RAW)
    {
        /* Just export the raw image as RGBA8 */
        IMG::serial_image img;
        img.size               = size;
        img.v2.bit_fmt         = BitFmt::UByte;
        img.v2.format.base_fmt = PixFmt::RGBA8;
        img.v2.format.c_flags  = CompFlags::CompressionNone;
        img.v2.format.p_flags  = PixFlg::None;

        auto rawName = outName.addExtension("raw");

        files.emplace_back(rawName, Bytes(), 0);

        auto& rawData = files.back().data;

        rawData = Bytes::Alloc(sizeof(img) + data.size);
        MemCpy(Bytes::From(img), rawData.at(0, sizeof(img)));
        MemCpy(data, rawData.at(sizeof(img)));

        cursor.progress(
            TEXCOMPRESS_API "Exporting raw RGBA for {0}", file.first);
    }
}
Example #4
0
Line Line::normal() const
{
    Size v = vector();
    //return Line(-v.cy(),v.cx(),v.cy(),-v.cx());
    return Line(0,0,v.cy(),-v.cx());
}
Example #5
0
 /**
     Greater-than-or-equal test.
     @param pt the other size to compare this to.
     @return true if the test is successful.
  */
 bool operator >= (const Size<T> &pt) const {
     return getArea() >= pt.getArea();
 }
Example #6
0
void
Widget::setSize(const Size &size)
{
  setWidth(size.width());
  setHeight(size.height());
}
Example #7
0
void UITextEdit::update(bool focusCursor)
{
    if(!m_updatesEnabled)
        return;

    std::string text = getDisplayedText();
    m_drawText = text;
    int textLength = text.length();

    // prevent glitches
    if(m_rect.isEmpty())
        return;

    // map glyphs positions
    Size textBoxSize;
    const std::vector<Point>& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize);
    const Rect *glyphsTextureCoords = m_font->getGlyphsTextureCoords();
    const Size *glyphsSize = m_font->getGlyphsSize();
    int glyph;

    // update rect size
    if(!m_rect.isValid() || m_textHorizontalAutoResize || m_textVerticalAutoResize) {
        textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom) + m_textOffset.toSize();
        Size size = getSize();
        if(size.width() <= 0 || (m_textHorizontalAutoResize && !m_textWrap))
            size.setWidth(textBoxSize.width());
        if(size.height() <= 0 || m_textVerticalAutoResize)
            size.setHeight(textBoxSize.height());
        setSize(size);
    }

    // resize just on demand
    if(textLength > (int)m_glyphsCoords.size()) {
        m_glyphsCoords.resize(textLength);
        m_glyphsTexCoords.resize(textLength);
    }

    Point oldTextAreaOffset = m_textVirtualOffset;

    if(textBoxSize.width() <= getPaddingRect().width())
        m_textVirtualOffset.x = 0;
    if(textBoxSize.height() <= getPaddingRect().height())
        m_textVirtualOffset.y = 0;

    // readjust start view area based on cursor position
    m_cursorInRange = false;
    if(focusCursor && m_autoScroll) {
        if(m_cursorPos > 0 && textLength > 0) {
                assert(m_cursorPos <= textLength);
                Rect virtualRect(m_textVirtualOffset, m_rect.size() - Size(m_padding.left+m_padding.right, 0)); // previous rendered virtual rect
                int pos = m_cursorPos - 1; // element before cursor
                glyph = (uchar)text[pos]; // glyph of the element before cursor
                Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]);

                // if the cursor is not on the previous rendered virtual rect we need to update it
                if(!virtualRect.contains(glyphRect.topLeft()) || !virtualRect.contains(glyphRect.bottomRight())) {
                    // calculate where is the first glyph visible
                    Point startGlyphPos;
                    startGlyphPos.y = std::max<int>(glyphRect.bottom() - virtualRect.height(), 0);
                    startGlyphPos.x = std::max<int>(glyphRect.right() - virtualRect.width(), 0);

                    // find that glyph
                    for(pos = 0; pos < textLength; ++pos) {
                        glyph = (uchar)text[pos];
                        glyphRect = Rect(glyphsPositions[pos], glyphsSize[glyph]);
                        glyphRect.setTop(std::max<int>(glyphRect.top() - m_font->getYOffset() - m_font->getGlyphSpacing().height(), 0));
                        glyphRect.setLeft(std::max<int>(glyphRect.left() - m_font->getGlyphSpacing().width(), 0));

                        // first glyph entirely visible found
                        if(glyphRect.topLeft() >= startGlyphPos) {
                            m_textVirtualOffset.x = glyphsPositions[pos].x;
                            m_textVirtualOffset.y = glyphsPositions[pos].y - m_font->getYOffset();
                            break;
                        }
                    }
                }
        } else {
            m_textVirtualOffset = Point(0,0);
        }
        m_cursorInRange = true;
    } else {
        if(m_cursorPos > 0 && textLength > 0) {
            Rect virtualRect(m_textVirtualOffset, m_rect.size() - Size(2*m_padding.left+m_padding.right, 0) ); // previous rendered virtual rect
            int pos = m_cursorPos - 1; // element before cursor
            glyph = (uchar)text[pos]; // glyph of the element before cursor
            Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]);
            if(virtualRect.contains(glyphRect.topLeft()) && virtualRect.contains(glyphRect.bottomRight()))
                m_cursorInRange = true;
        } else {
            m_cursorInRange = true;
        }
    }

    bool fireAreaUpdate = false;
    if(oldTextAreaOffset != m_textVirtualOffset)
        fireAreaUpdate = true;

    Rect textScreenCoords = m_rect;
    textScreenCoords.expandLeft(-m_padding.left);
    textScreenCoords.expandRight(-m_padding.right);
    textScreenCoords.expandBottom(-m_padding.bottom);
    textScreenCoords.expandTop(-m_padding.top);
    m_drawArea = textScreenCoords;

    if(textScreenCoords.size() != m_textVirtualSize) {
        m_textVirtualSize = textScreenCoords.size();
        fireAreaUpdate = true;
    }

    Size totalSize = textBoxSize;
    if(totalSize.width() < m_textVirtualSize.width())
        totalSize.setWidth(m_textVirtualSize.height());
    if(totalSize.height() < m_textVirtualSize.height())
        totalSize.setHeight(m_textVirtualSize.height());
    if(m_textTotalSize != totalSize) {
        m_textTotalSize = totalSize;
        fireAreaUpdate = true;
    }

    if(m_textAlign & Fw::AlignBottom) {
        m_drawArea.translate(0, textScreenCoords.height() - textBoxSize.height());
    } else if(m_textAlign & Fw::AlignVerticalCenter) {
        m_drawArea.translate(0, (textScreenCoords.height() - textBoxSize.height()) / 2);
    } else { // AlignTop
    }

    if(m_textAlign & Fw::AlignRight) {
        m_drawArea.translate(textScreenCoords.width() - textBoxSize.width(), 0);
    } else if(m_textAlign & Fw::AlignHorizontalCenter) {
        m_drawArea.translate((textScreenCoords.width() - textBoxSize.width()) / 2, 0);
    } else { // AlignLeft

    }

    for(int i = 0; i < textLength; ++i) {
        glyph = (uchar)text[i];
        m_glyphsCoords[i].clear();

        // skip invalid glyphs
        if(glyph < 32 && glyph != (uchar)'\n')
            continue;

        // calculate initial glyph rect and texture coords
        Rect glyphScreenCoords(glyphsPositions[i], glyphsSize[glyph]);
        Rect glyphTextureCoords = glyphsTextureCoords[glyph];

        // first translate to align position
        if(m_textAlign & Fw::AlignBottom) {
            glyphScreenCoords.translate(0, textScreenCoords.height() - textBoxSize.height());
        } else if(m_textAlign & Fw::AlignVerticalCenter) {
            glyphScreenCoords.translate(0, (textScreenCoords.height() - textBoxSize.height()) / 2);
        } else { // AlignTop
            // nothing to do
        }

        if(m_textAlign & Fw::AlignRight) {
            glyphScreenCoords.translate(textScreenCoords.width() - textBoxSize.width(), 0);
        } else if(m_textAlign & Fw::AlignHorizontalCenter) {
            glyphScreenCoords.translate((textScreenCoords.width() - textBoxSize.width()) / 2, 0);
        } else { // AlignLeft
            // nothing to do
        }

        // only render glyphs that are after startRenderPosition
        if(glyphScreenCoords.bottom() < m_textVirtualOffset.y || glyphScreenCoords.right() < m_textVirtualOffset.x)
            continue;

        // bound glyph topLeft to startRenderPosition
        if(glyphScreenCoords.top() < m_textVirtualOffset.y) {
            glyphTextureCoords.setTop(glyphTextureCoords.top() + (m_textVirtualOffset.y - glyphScreenCoords.top()));
            glyphScreenCoords.setTop(m_textVirtualOffset.y);
        }
        if(glyphScreenCoords.left() < m_textVirtualOffset.x) {
            glyphTextureCoords.setLeft(glyphTextureCoords.left() + (m_textVirtualOffset.x - glyphScreenCoords.left()));
            glyphScreenCoords.setLeft(m_textVirtualOffset.x);
        }

        // subtract startInternalPos
        glyphScreenCoords.translate(-m_textVirtualOffset);

        // translate rect to screen coords
        glyphScreenCoords.translate(textScreenCoords.topLeft());

        // only render if glyph rect is visible on screenCoords
        if(!textScreenCoords.intersects(glyphScreenCoords))
            continue;

        // bound glyph bottomRight to screenCoords bottomRight
        if(glyphScreenCoords.bottom() > textScreenCoords.bottom()) {
            glyphTextureCoords.setBottom(glyphTextureCoords.bottom() + (textScreenCoords.bottom() - glyphScreenCoords.bottom()));
            glyphScreenCoords.setBottom(textScreenCoords.bottom());
        }
        if(glyphScreenCoords.right() > textScreenCoords.right()) {
            glyphTextureCoords.setRight(glyphTextureCoords.right() + (textScreenCoords.right() - glyphScreenCoords.right()));
            glyphScreenCoords.setRight(textScreenCoords.right());
        }

        // render glyph
        m_glyphsCoords[i] = glyphScreenCoords;
        m_glyphsTexCoords[i] = glyphTextureCoords;
    }

    if(fireAreaUpdate)
        onTextAreaUpdate(m_textVirtualOffset, m_textVirtualSize, m_textTotalSize);

    g_app.repaint();
}
Example #8
0
 /**
     Creates a subbitmap.
     @param parent parent bitmap.
     @param pt point of origin in the parent.
     @param size size.
  */
 Bitmap(Bitmap &parent, const Point<int> &pt, const Size<int> &size) :
     Shared(al_create_sub_bitmap(parent.get(), pt.getX(), pt.getY(), size.getWidth(), size.getHeight()), al_destroy_bitmap)
 {
 }
void NodeHorizontal::updateLeftPos()
{
    using namespace NodeHorizontal_impl;
    Size leftSize = left->getCurrentSize();
    left->setCurrentTopLeft(Point(leftPadding,(getCurrentSize().height()-topPadding-bottomPadding-leftSize.height())/2+topPadding),getCurrentSize());
}
Example #10
0
	void* get() { if (size_.bytes() == 0) return 0;
	              return &data[0]; }
 Point computeRightChildPoint(Point const&myNotationPos,Size const&notationSize)
 {
     return myNotationPos+Point(notationSize.width()+middlePadding,0);
 }
 Point computeLeftChildPos(Size const&mySize,Size const&leftSize)
 {
     return Point(0,(mySize.height()-leftSize.height())/2);//垂直方向上居中
 }
void MediaDispatcherImpl::OnVideoDecode(VideoDecodeEventArgs const& e)
{
	VideoSource const& s = e.Source();
	
	int32 channel = s.Channel(); 

	if (mNeedWaitI[channel])
	{
		if (s.Type() == VideoType_H264_IFrame)
			mNeedWaitI[channel] = false;
		else
			return;
	}
		
	if (mVideoMode[channel].Width() != s.Width() || mVideoMode[channel].Height() != s.Height())
	{
		mVideoMode[channel] = Size(s.Width(), s.Height());
		DisposeVideoDecoder(channel);
	}

	JNIEnv* env = GetJNIEnvAttachThread();

	if (mVideoDecoder[channel] == NULL)
		CreateVideoDecoder(env, channel, s.Width(), s.Height()); // create decoder and buffer

	
	jintArray outputSize = env->NewIntArray(3);
	jint* _outputSize = env->GetIntArrayElements(outputSize, 0);

	
	//
	
	jobjectArray videoBuffer2d = env->CallObjectMethod(mObject, methods.MediaDispatcher_GetVideoBuffer, channel);

	jbyteArray y = (jbyteArray) env->GetObjectArrayElement(videoBuffer2d, (jsize) 0);
	jbyteArray u = (jbyteArray) env->GetObjectArrayElement(videoBuffer2d, (jsize) 1);
	jbyteArray v = (jbyteArray) env->GetObjectArrayElement(videoBuffer2d, (jsize) 2);
	jbyte* _y = env->GetByteArrayElements(y, 0); // not copy array
	jbyte* _u = env->GetByteArrayElements(u, 0); // not copy array
	jbyte* _v = env->GetByteArrayElements(v, 0); // not copy array

	byte*  output[3] = { (byte*) _y, (byte*) _u, (byte*) _v };
	//
	
	Size      resolution;
	Thickness cropped;
	
	if (mVideoDecoder[channel]->Decode(s.Buffer(), s.BufferLength(), VideoPixelFormat_I420, output, _outputSize, resolution, cropped))
	{
		int32 dstW = resolution.Width() - cropped.Left() - cropped.Right();
		int32 dstH = resolution.Height() - cropped.Top() - cropped.Bottom();
		env->CallVoidMethod(mObject, methods.VideoFrameDecodedListener_OnVideoOneFrameDecoded, channel, 
						dstW, dstH, outputSize, VideoPixelFormat_I420, cropped.Left(), cropped.Top());
	}

	else
	{
		LOGE("decode error: %d", channel);
	}

	
	
	env->ReleaseByteArrayElements(y, _y, 0);
	env->ReleaseByteArrayElements(u, _u, 0);
	env->ReleaseByteArrayElements(v, _v, 0);
	env->DeleteLocalRef(y);
	env->DeleteLocalRef(u);
	env->DeleteLocalRef(v);
	env->DeleteLocalRef(videoBuffer2d);
	
	env->ReleaseIntArrayElements(outputSize, _outputSize, 0); // mode: copy back the content and free the elems buffer
	                                                          // MUST to free the elems buffer, because elems buffer holds
															  // a local reference, which needs to delete
	env->DeleteLocalRef(outputSize);
	
	JNIEnvDeattachThread();
}
Example #14
0
void X11Window::resize(const Size& size)
{
    XResizeWindow(m_display, m_window, size.width(), size.height());
}
bool RasterCoverageConnector::store(IlwisObject *obj, const IOOptions & )
{
    if(!loadDriver())
        return false;

    RasterCoverage *raster = static_cast<RasterCoverage *>(obj);

    DataDefinition currentDef = raster->datadefRef();
    if (! hasType(raster->datadef().domain()->ilwisType(),itNUMERICDOMAIN | itCOLORDOMAIN)){
        IDomain dom;
        QString code = raster->datadef().domain()->ilwisType() == itITEMDOMAIN ? "code=count" : "code=value";
        if(!dom.prepare(code)) { //TODO:  for the moment only value maps in gdal
            return ERROR1(ERR_NO_INITIALIZED_1,obj->name());
        }
        currentDef.domain(dom);
    }
    Size<> sz = raster->size();
    GDALDataType gdalType = ilwisType2GdalType(currentDef.range()->valueType());
    QString filename = constructOutputName(_driver);
    bool isColorMap = currentDef.domain()->ilwisType() == itCOLORDOMAIN;
    bool ispaletteMap = currentDef.domain()->valueType() == itPALETTECOLOR;

    GDALDatasetH dataset = 0;
    if ( ispaletteMap && format() == "GTiff"){
        char *options[] = {"PHOTOMETRIC=PALETTE", NULL};
        dataset = gdal()->create( _driver, filename.toLocal8Bit(), sz.xsize(), sz.ysize(),  sz.zsize(), gdalType, options );
    }else
        dataset = gdal()->create( _driver, filename.toLocal8Bit(), sz.xsize(), sz.ysize(),  isColorMap ?  sz.zsize() * 3 : sz.zsize(), gdalType, 0 );
    if ( dataset == 0) {
        return ERROR2(ERR_COULDNT_CREATE_OBJECT_FOR_2, "data set",_fileUrl.toLocalFile());
    }
    bool ok = setGeotransform(raster, dataset);
    if (ok)
        ok = setSRS(raster, dataset);

    if (!ok)
        return false;

    if ( isColorMap ){
        ok = storeColorRaster(raster, dataset)    ;
    } else {
        switch(gdalType) {
        case GDT_Byte:
            ok = save<quint8>(raster, dataset,gdalType);break;
        case GDT_UInt16:
            ok = save<quint16>(raster, dataset,gdalType);break;
        case GDT_Int16:
            ok = save<qint16>(raster, dataset,gdalType);break;
        case GDT_Int32:
            ok = save<qint32>(raster, dataset,gdalType);break;
        case GDT_UInt32:
            ok = save<quint32>(raster, dataset,gdalType);break;
        case GDT_Float32:
            ok = save<float>(raster, dataset,gdalType);break;
        case GDT_Float64:
            ok = save<double>(raster, dataset,gdalType);break;
        default:
            ok= ERROR1(ERR_NO_INITIALIZED_1, "gdal Data type");
        }
    }

    gdal()->close(dataset);

    return ok;
}
Example #16
0
 /**
     Creates a bitmap of the specific size.
     @param size size.
  */
 Bitmap(const Size<int> &size) : Shared(al_create_bitmap(size.getWidth(), size.getHeight()), al_destroy_bitmap) {
 }
/*!
    \fn swUiControl::Resize( const Size& newSize )
 */
void swUiControl::Resize( const Size& newSize )
{
    SetGeometry(Rect ( m_geometry.x(), m_geometry.y(), newSize.width(), newSize.height() ));
}
Example #18
0
llvm::Constant *
IRGenModule::getAddrOfKeyPathPattern(KeyPathPattern *pattern,
                                     SILLocation diagLoc) {
  // See if we already emitted this.
  auto found = KeyPathPatterns.find(pattern);
  if (found != KeyPathPatterns.end())
    return found->second;
  
  // Gather type arguments from the root and leaf types of the key path.
  auto rootTy = pattern->getRootType();
  auto valueTy = pattern->getValueType();

  // Check for parameterization, whether by subscript indexes or by the generic
  // environment. If there isn't any, we can instantiate the pattern in-place.
  bool isInstantiableInPlace = pattern->getNumOperands() == 0
    && !pattern->getGenericSignature();

  // Collect the required parameters for the keypath's generic environment.
  SmallVector<GenericRequirement, 4> requirements;
  
  GenericEnvironment *genericEnv = nullptr;
  if (auto sig = pattern->getGenericSignature()) {
    genericEnv = sig->createGenericEnvironment(*getSwiftModule());
    enumerateGenericSignatureRequirements(pattern->getGenericSignature(),
      [&](GenericRequirement reqt) { requirements.push_back(reqt); });
  }

  /// Generate a metadata accessor that produces metadata for the given type
  /// using arguments from the generic context of the key path.
  auto emitMetadataGenerator = [&](CanType type) -> llvm::Function * {
    // TODO: Use the standard metadata accessor when there are no arguments
    // and the metadata accessor is defined.
    
    // Build a stub that loads the necessary bindings from the key path's
    // argument buffer then fetches the metadata.
    auto fnTy = llvm::FunctionType::get(TypeMetadataPtrTy,
                                        {Int8PtrTy}, /*vararg*/ false);
    auto accessorThunk = llvm::Function::Create(fnTy,
                                              llvm::GlobalValue::PrivateLinkage,
                                              "keypath_get_type", getModule());
    accessorThunk->setAttributes(constructInitialAttributes());
    {
      IRGenFunction IGF(*this, accessorThunk);
      if (DebugInfo)
        DebugInfo->emitArtificialFunction(IGF, accessorThunk);

      if (type->hasTypeParameter()) {
        auto bindingsBufPtr = IGF.collectParameters().claimNext();

        bindFromGenericRequirementsBuffer(IGF, requirements,
          Address(bindingsBufPtr, getPointerAlignment()),
          [&](CanType t) {
            if (!genericEnv)
              return t;
            return genericEnv->mapTypeIntoContext(t)->getCanonicalType();
          });
      
        type = genericEnv->mapTypeIntoContext(type)->getCanonicalType();
      }
      auto ret = IGF.emitTypeMetadataRef(type);
      IGF.Builder.CreateRet(ret);
    }
    return accessorThunk;
  };
  
  // Start building the key path pattern.
  ConstantInitBuilder builder(*this);
  ConstantStructBuilder fields = builder.beginStruct();
  fields.setPacked(true);
  // Add a zero-initialized header we can use for lazy initialization.
  fields.add(llvm::ConstantInt::get(SizeTy, 0));

#ifndef NDEBUG
  auto startOfObject = fields.getNextOffsetFromGlobal();
#endif

  // Store references to metadata generator functions to generate the metadata
  // for the root and leaf. These sit in the "isa" and object header parts of
  // the final object.
  fields.add(emitMetadataGenerator(rootTy));
  fields.add(emitMetadataGenerator(valueTy));
  
  // TODO: 32-bit still has a padding word
  if (SizeTy == Int32Ty) {
    fields.addInt32(0);
  }
  
#ifndef NDEBUG
  auto endOfObjectHeader = fields.getNextOffsetFromGlobal();
  unsigned expectedObjectHeaderSize;
  if (SizeTy == Int64Ty)
    expectedObjectHeaderSize = SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_64;
  else if (SizeTy == Int32Ty)
    expectedObjectHeaderSize = SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_32;
  else
    llvm_unreachable("unexpected pointer size");
  assert((endOfObjectHeader - startOfObject).getValue()
            == expectedObjectHeaderSize
       && "key path pattern header size doesn't match heap object header size");
#endif
  
  // Add a pointer to the ObjC KVC compatibility string, if there is one, or
  // null otherwise.
  llvm::Constant *objcString;
  if (!pattern->getObjCString().empty()) {
    objcString = getAddrOfGlobalString(pattern->getObjCString());
  } else {
    objcString = llvm::ConstantPointerNull::get(Int8PtrTy);
  }
  fields.add(objcString);
  
  // Leave a placeholder for the buffer header, since we need to know the full
  // buffer size to fill it in.
  auto headerPlaceholder = fields.addPlaceholderWithSize(Int32Ty);
  
  auto startOfKeyPathBuffer = fields.getNextOffsetFromGlobal();
  
  // Build out the components.
  auto baseTy = rootTy;
  
  auto getPropertyOffsetOrIndirectOffset
    = [&](SILType loweredBaseTy, VarDecl *property)
        -> std::pair<llvm::Constant*, bool> {
      llvm::Constant *offset;
      bool isResolved;
      bool isStruct;
      if (loweredBaseTy.getStructOrBoundGenericStruct()) {
        offset = emitPhysicalStructMemberFixedOffset(*this,
                                                     loweredBaseTy,
                                                     property);
        isStruct = true;
      } else if (loweredBaseTy.getClassOrBoundGenericClass()) {
        offset = tryEmitConstantClassFragilePhysicalMemberOffset(*this,
                                                                 loweredBaseTy,
                                                                 property);
        isStruct = false;
      } else {
        llvm_unreachable("property of non-struct, non-class?!");
      }
      
      // If the offset isn't fixed, try instead to get the field offset vector
      // offset for the field to look it up dynamically.
      isResolved = offset != nullptr;
      if (!isResolved) {
        if (isStruct) {
          offset = emitPhysicalStructMemberOffsetOfFieldOffset(
                                                *this, loweredBaseTy, property);
          assert(offset && "field is neither fixed-offset nor in offset vector");
        } else {
          auto offsetValue = getClassFieldOffset(*this,
                                loweredBaseTy.getClassOrBoundGenericClass(),
                                property);
          offset = llvm::ConstantInt::get(Int32Ty, offsetValue.getValue());
        }
      }
      
      return {offset, isResolved};
    };
  
  for (unsigned i : indices(pattern->getComponents())) {
    SILType loweredBaseTy;
    Lowering::GenericContextScope scope(getSILTypes(),
                                        pattern->getGenericSignature());
    loweredBaseTy = getLoweredType(AbstractionPattern::getOpaque(),
                                   baseTy->getLValueOrInOutObjectType());

    auto &component = pattern->getComponents()[i];
    switch (auto kind = component.getKind()) {
    case KeyPathPatternComponent::Kind::StoredProperty: {
      // Try to get a constant offset if we can.
      auto property = cast<VarDecl>(component.getStoredPropertyDecl());
      llvm::Constant *offset;
      bool isResolved;
      std::tie(offset, isResolved)
        = getPropertyOffsetOrIndirectOffset(loweredBaseTy, property);
      offset = llvm::ConstantExpr::getTruncOrBitCast(offset, Int32Ty);
      bool isStruct = (bool)loweredBaseTy.getStructOrBoundGenericStruct();
      
      // If the projection is a statically known integer, try to pack it into
      // the key path payload.
      if (isResolved) {
        if (auto offsetInt = dyn_cast_or_null<llvm::ConstantInt>(offset)) {
          auto offsetValue = offsetInt->getValue().getZExtValue();
          if (KeyPathComponentHeader::offsetCanBeInline(offsetValue)) {
            auto header = isStruct
              ? KeyPathComponentHeader::forStructComponentWithInlineOffset(offsetValue)
              : KeyPathComponentHeader::forClassComponentWithInlineOffset(offsetValue);
            fields.addInt32(header.getData());
            break;
          }
        }
      
        auto header = isStruct
          ? KeyPathComponentHeader::forStructComponentWithOutOfLineOffset()
          : KeyPathComponentHeader::forClassComponentWithOutOfLineOffset();
        fields.addInt32(header.getData());
        
        fields.add(offset);
      } else {
        // Otherwise, stash the offset of the field offset within the metadata
        // object, so we can pull it out at instantiation time.
        // TODO: We'll also need a way to handle resilient field offsets, once
        // field offset vectors no longer cover all fields in the type.
        KeyPathComponentHeader header = isStruct
          ? KeyPathComponentHeader::forStructComponentWithUnresolvedOffset()
          : KeyPathComponentHeader::forClassComponentWithUnresolvedOffset();
        fields.addInt32(header.getData());
        fields.add(offset);
      }
      break;
    }
    case KeyPathPatternComponent::Kind::GettableProperty:
    case KeyPathPatternComponent::Kind::SettableProperty: {
      // Encode the settability.
      bool settable = kind == KeyPathPatternComponent::Kind::SettableProperty;
      KeyPathComponentHeader::ComputedPropertyKind componentKind;
      if (settable) {
        componentKind = component.isComputedSettablePropertyMutating()
          ? KeyPathComponentHeader::SettableMutating
          : KeyPathComponentHeader::SettableNonmutating;
      } else {
        componentKind = KeyPathComponentHeader::GetOnly;
      }
      
      // Lower the id reference.
      auto id = component.getComputedPropertyId();
      KeyPathComponentHeader::ComputedPropertyIDKind idKind;
      llvm::Constant *idValue;
      bool idResolved;
      switch (id.getKind()) {
      case KeyPathPatternComponent::ComputedPropertyId::Function:
        idKind = KeyPathComponentHeader::Pointer;
        idValue = getAddrOfSILFunction(id.getFunction(), NotForDefinition);
        idResolved = true;
        break;
      case KeyPathPatternComponent::ComputedPropertyId::DeclRef: {
        auto declRef = id.getDeclRef();
      
        // Foreign method refs identify using a selector
        // reference, which is doubly-indirected and filled in with a unique
        // pointer by dyld.
        if (declRef.isForeign) {
          assert(ObjCInterop && "foreign keypath component w/o objc interop?!");
          idKind = KeyPathComponentHeader::Pointer;
          idValue = getAddrOfObjCSelectorRef(declRef);
          idResolved = false;
        } else {
          idKind = KeyPathComponentHeader::VTableOffset;
          auto dc = declRef.getDecl()->getDeclContext();
          if (isa<ClassDecl>(dc)) {
            auto index = getVirtualMethodIndex(*this, declRef);
            idValue = llvm::ConstantInt::get(SizeTy, index);
            idResolved = true;
          } else if (auto methodProto = dyn_cast<ProtocolDecl>(dc)) {
            auto &protoInfo = getProtocolInfo(methodProto);
            auto index = protoInfo.getFunctionIndex(
                                 cast<AbstractFunctionDecl>(declRef.getDecl()));
            idValue = llvm::ConstantInt::get(SizeTy, -index.getValue());
            idResolved = true;
          } else {
            llvm_unreachable("neither a class nor protocol dynamic method?");
          }
        }
        break;
      }
      case KeyPathPatternComponent::ComputedPropertyId::Property:
        idKind = KeyPathComponentHeader::StoredPropertyOffset;
        std::tie(idValue, idResolved) =
          getPropertyOffsetOrIndirectOffset(loweredBaseTy, id.getProperty());
        idValue = llvm::ConstantExpr::getZExtOrBitCast(idValue, SizeTy);
        break;
      }
      
      auto header = KeyPathComponentHeader::forComputedProperty(componentKind,
                                    idKind, !isInstantiableInPlace, idResolved);
      
      fields.addInt32(header.getData());
      fields.add(idValue);
      
      if (isInstantiableInPlace) {
        // No generic arguments, so we can invoke the getter/setter as is.
        fields.add(getAddrOfSILFunction(component.getComputedPropertyGetter(),
                                        NotForDefinition));
        if (settable)
          fields.add(getAddrOfSILFunction(component.getComputedPropertySetter(),
                                          NotForDefinition));
      } else {
        // If there's generic context (TODO: or subscript indexes), embed as
        // arguments in the component. Thunk the SIL-level accessors to give the
        // runtime implementation a polymorphically-callable interface.
        Context.Diags.diagnose(diagLoc.getSourceLoc(),
                               diag::not_implemented,
                               "generic computed key paths");
        return llvm::UndefValue::get(Int8PtrTy);
      }
    }
    }
    
    // For all but the last component, we pack in the type of the component.
    if (i + 1 != pattern->getComponents().size()) {
      fields.add(emitMetadataGenerator(component.getComponentType()));
    }
    baseTy = component.getComponentType();
  }
  
  // Save the total size of the buffer.
  Size componentSize = fields.getNextOffsetFromGlobal()
    - startOfKeyPathBuffer;
  
  // We now have enough info to build the header.
  KeyPathBufferHeader header(componentSize.getValue(), isInstantiableInPlace,
                             /*reference prefix*/ false);
  // Add the header, followed by the components.
  fields.fillPlaceholder(headerPlaceholder,
                         llvm::ConstantInt::get(Int32Ty, header.getData()));
  
  // Create the global variable.
  // TODO: The pattern could be immutable if
  // it isn't instantiable in place, and if we made the type metadata accessor
  // references private, it could go in true-const memory.
  auto patternVar = fields.finishAndCreateGlobal("keypath",
                                          getPointerAlignment(),
                                          /*constant*/ false,
                                          llvm::GlobalVariable::PrivateLinkage);
  KeyPathPatterns.insert({pattern, patternVar});
  return patternVar;
}
Example #19
0
 /**
     Less-than test.
     @param pt the other size to compare this to.
     @return true if the test is successful.
  */
 bool operator < (const Size<T> &pt) const {
     return getArea() < pt.getArea();
 }