Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/vcl/source/bitmap/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 16 kB image not shown  

Quelle  BitmapReadAccess.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <vcl/BitmapReadAccess.hxx>
#include <vcl/BitmapTools.hxx>

#include <salbmp.hxx>
#include <svdata.hxx>
#include <salinst.hxx>

BitmapReadAccess::BitmapReadAccess(const AlphaMask& rBitmap, BitmapAccessMode nMode)
    : BitmapReadAccess(rBitmap.GetBitmap(), nMode)
{
}

BitmapReadAccess::BitmapReadAccess(const Bitmap& rBitmap, BitmapAccessMode nMode)
    : BitmapInfoAccess(rBitmap, nMode)
    , mFncGetPixel(nullptr)
    , mFncSetPixel(nullptr)
{
    if (!mpBuffer)
        return;

    const std::shared_ptr<SalBitmap>& xImpBmp = rBitmap.ImplGetSalBitmap();
    if (!xImpBmp)
        return;

    mFncGetPixel = GetPixelFunction(mpBuffer->meFormat);
    mFncSetPixel = SetPixelFunction(mpBuffer->meFormat);

    if (!mFncGetPixel || !mFncSetPixel)
    {
        xImpBmp->ReleaseBuffer(mpBuffer, mnAccessMode);
        mpBuffer = nullptr;
    }
}

BitmapReadAccess::~BitmapReadAccess() {}

bool Bitmap32IsPreMultipled() { return ImplGetSVData()->mpDefInst->supportsBitmap32(); }

FncGetPixel BitmapReadAccess::GetPixelFunction(ScanlineFormat nFormat)
{
    switch (nFormat)
    {
        case ScanlineFormat::N1BitMsbPal:
            return GetPixelForN1BitMsbPal;
        case ScanlineFormat::N8BitPal:
            return GetPixelForN8BitPal;
        case ScanlineFormat::N24BitTcBgr:
            return GetPixelForN24BitTcBgr;
        case ScanlineFormat::N24BitTcRgb:
            return GetPixelForN24BitTcRgb;
        case ScanlineFormat::N32BitTcAbgr:
            assert(Bitmap32IsPreMultipled());
            return GetPixelForN32BitTcAbgr;
        case ScanlineFormat::N32BitTcXbgr:
            assert(!Bitmap32IsPreMultipled());
            return GetPixelForN32BitTcXbgr;
        case ScanlineFormat::N32BitTcArgb:
            assert(Bitmap32IsPreMultipled());
            return GetPixelForN32BitTcArgb;
        case ScanlineFormat::N32BitTcXrgb:
            assert(!Bitmap32IsPreMultipled());
            return GetPixelForN32BitTcXrgb;
        case ScanlineFormat::N32BitTcBgra:
            assert(Bitmap32IsPreMultipled());
            return GetPixelForN32BitTcBgra;
        case ScanlineFormat::N32BitTcBgrx:
            assert(!Bitmap32IsPreMultipled());
            return GetPixelForN32BitTcBgrx;
        case ScanlineFormat::N32BitTcRgba:
            assert(Bitmap32IsPreMultipled());
            return GetPixelForN32BitTcRgba;
        case ScanlineFormat::N32BitTcRgbx:
            assert(!Bitmap32IsPreMultipled());
            return GetPixelForN32BitTcRgbx;

        default:
            return nullptr;
    }
}

FncSetPixel BitmapReadAccess::SetPixelFunction(ScanlineFormat nFormat)
{
    switch (nFormat)
    {
        case ScanlineFormat::N1BitMsbPal:
            return SetPixelForN1BitMsbPal;
        case ScanlineFormat::N8BitPal:
            return SetPixelForN8BitPal;
        case ScanlineFormat::N24BitTcBgr:
            return SetPixelForN24BitTcBgr;
        case ScanlineFormat::N24BitTcRgb:
            return SetPixelForN24BitTcRgb;
        case ScanlineFormat::N32BitTcAbgr:
            assert(Bitmap32IsPreMultipled());
            return SetPixelForN32BitTcAbgr;
        case ScanlineFormat::N32BitTcXbgr:
            assert(!Bitmap32IsPreMultipled());
            return SetPixelForN32BitTcXbgr;
        case ScanlineFormat::N32BitTcArgb:
            assert(Bitmap32IsPreMultipled());
            return SetPixelForN32BitTcArgb;
        case ScanlineFormat::N32BitTcXrgb:
            assert(!Bitmap32IsPreMultipled());
            return SetPixelForN32BitTcXrgb;
        case ScanlineFormat::N32BitTcBgra:
            assert(Bitmap32IsPreMultipled());
            return SetPixelForN32BitTcBgra;
        case ScanlineFormat::N32BitTcBgrx:
            assert(!Bitmap32IsPreMultipled());
            return SetPixelForN32BitTcBgrx;
        case ScanlineFormat::N32BitTcRgba:
            assert(Bitmap32IsPreMultipled());
            return SetPixelForN32BitTcRgba;
        case ScanlineFormat::N32BitTcRgbx:
            assert(!Bitmap32IsPreMultipled());
            return SetPixelForN32BitTcRgbx;

        default:
            assert(false);
            return nullptr;
    }
}

BitmapColor BitmapReadAccess::GetInterpolatedColorWithFallback(double fY, double fX,
                                                               const BitmapColor& rFallback) const
{
    // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
    // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
    if (!mpBuffer || fX < 0.0 || fY < 0.0)
        return rFallback;

    const sal_Int64 nX(static_cast<sal_Int64>(fX));
    const sal_Int64 nY(static_cast<sal_Int64>(fY));

    if (nX >= mpBuffer->mnWidth || nY >= mpBuffer->mnHeight)
        return rFallback;

    // get base-return value from inside pixel
    BitmapColor aRetval(GetColor(nY, nX));

    // calculate deltas and indices for neighbour accesses
    sal_Int16 nDeltaX((fX - (nX + 0.5)) * 255.0); // [-255 .. 255]
    sal_Int16 nDeltaY((fY - (nY + 0.5)) * 255.0); // [-255 .. 255]
    sal_Int16 nIndX(0);
    sal_Int16 nIndY(0);

    if (nDeltaX > 0)
    {
        nIndX = nX + 1;
    }
    else
    {
        nIndX = nX - 1;
        nDeltaX = -nDeltaX;
    }

    if (nDeltaY > 0)
    {
        nIndY = nY + 1;
    }
    else
    {
        nIndY = nY - 1;
        nDeltaY = -nDeltaY;
    }

    // get right/left neighbour
    BitmapColor aXCol(rFallback);

    if (nDeltaX && nIndX >= 0 && nIndX < mpBuffer->mnWidth)
        aXCol = GetColor(nY, nIndX);

    // get top/bottom neighbour
    BitmapColor aYCol(rFallback);

    if (nDeltaY && nIndY >= 0 && nIndY < mpBuffer->mnHeight)
        aYCol = GetColor(nIndY, nX);

    // get one of four edge neighbours
    BitmapColor aXYCol(rFallback);

    if (nDeltaX && nDeltaY && nIndX >= 0 && nIndY >= 0 && nIndX < mpBuffer->mnWidth
        && nIndY < mpBuffer->mnHeight)
    {
        aXYCol = GetColor(nIndY, nIndX);
    }

    // merge return value with right/left neighbour
    if (aXCol != aRetval)
        aRetval.Merge(aXCol, 255 - nDeltaX);

    // merge top/bottom neighbour with edge
    if (aYCol != aXYCol)
        aYCol.Merge(aXYCol, 255 - nDeltaX);

    // merge return value with already merged top/bottom neighbour
    if (aRetval != aYCol)
        aRetval.Merge(aYCol, 255 - nDeltaY);

    return aRetval;
}

BitmapColor BitmapReadAccess::GetColorWithFallback(double fY, double fX,
                                                   const BitmapColor& rFallback) const
{
    // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
    // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
    if (!mpBuffer || fX < 0.0 || fY < 0.0)
        return rFallback;

    const sal_Int32 nX(static_cast<sal_Int32>(fX));
    const sal_Int32 nY(static_cast<sal_Int32>(fY));

    if (nX >= mpBuffer->mnWidth || nY >= mpBuffer->mnHeight)
        return rFallback;

    return GetColor(nY, nX);
}

BitmapColor BitmapReadAccess::GetPixelForN1BitMsbPal(ConstScanline pScanline, tools::Long nX)
{
    return BitmapColor(pScanline[nX >> 3] & (1 << (7 - (nX & 7))) ? 1 : 0);
}

void BitmapReadAccess::SetPixelForN1BitMsbPal(const Scanline pScanline, tools::Long nX,
                                              const BitmapColor& rBitmapColor)
{
    sal_uInt8& rByte = pScanline[nX >> 3];

    if (rBitmapColor.GetIndex() & 1)
        rByte |= 1 << (7 - (nX & 7));
    else
        rByte &= ~(1 << (7 - (nX & 7)));
}

BitmapColor BitmapReadAccess::GetPixelForN8BitPal(ConstScanline pScanline, tools::Long nX)
{
    return BitmapColor(pScanline[nX]);
}

void BitmapReadAccess::SetPixelForN8BitPal(Scanline pScanline, tools::Long nX,
                                           const BitmapColor& rBitmapColor)
{
    pScanline[nX] = rBitmapColor.GetIndex();
}

BitmapColor BitmapReadAccess::GetPixelForN24BitTcBgr(ConstScanline pScanline, tools::Long nX)
{
    BitmapColor aBitmapColor;

    pScanline = pScanline + nX * 3;
    aBitmapColor.SetBlue(*pScanline++);
    aBitmapColor.SetGreen(*pScanline++);
    aBitmapColor.SetRed(*pScanline);

    return aBitmapColor;
}

void BitmapReadAccess::SetPixelForN24BitTcBgr(Scanline pScanline, tools::Long nX,
                                              const BitmapColor& rBitmapColor)
{
    pScanline = pScanline + nX * 3;
    *pScanline++ = rBitmapColor.GetBlue();
    *pScanline++ = rBitmapColor.GetGreen();
    *pScanline = rBitmapColor.GetRed();
}

BitmapColor BitmapReadAccess::GetPixelForN24BitTcRgb(ConstScanline pScanline, tools::Long nX)
{
    BitmapColor aBitmapColor;

    pScanline = pScanline + nX * 3;
    aBitmapColor.SetRed(*pScanline++);
    aBitmapColor.SetGreen(*pScanline++);
    aBitmapColor.SetBlue(*pScanline);

    return aBitmapColor;
}

void BitmapReadAccess::SetPixelForN24BitTcRgb(Scanline pScanline, tools::Long nX,
                                              const BitmapColor& rBitmapColor)
{
    pScanline = pScanline + nX * 3;
    *pScanline++ = rBitmapColor.GetRed();
    *pScanline++ = rBitmapColor.GetGreen();
    *pScanline = rBitmapColor.GetBlue();
}

BitmapColor BitmapReadAccess::GetPixelForN32BitTcAbgr(ConstScanline pScanline, tools::Long nX)
{
    pScanline = pScanline + nX * 4;

    sal_uInt8 a = *pScanline++;
    sal_uInt8 b = *pScanline++;
    sal_uInt8 g = *pScanline++;
    sal_uInt8 r = *pScanline;

    return BitmapColor(ColorAlpha, vcl::bitmap::unpremultiply(r, a),
                       vcl::bitmap::unpremultiply(g, a), vcl::bitmap::unpremultiply(b, a), a);
}

BitmapColor BitmapReadAccess::GetPixelForN32BitTcXbgr(ConstScanline pScanline, tools::Long nX)
{
    BitmapColor aBitmapColor;

    pScanline = pScanline + (nX << 2) + 1;
    aBitmapColor.SetBlue(*pScanline++);
    aBitmapColor.SetGreen(*pScanline++);
    aBitmapColor.SetRed(*pScanline);

    return aBitmapColor;
}

void BitmapReadAccess::SetPixelForN32BitTcAbgr(Scanline pScanline, tools::Long nX,
                                               const BitmapColor& rBitmapColor)
{
    pScanline = pScanline + nX * 4;

    sal_uInt8 alpha = rBitmapColor.GetAlpha();
    *pScanline++ = alpha;
    *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
    *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
    *pScanline = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
}

void BitmapReadAccess::SetPixelForN32BitTcXbgr(Scanline pScanline, tools::Long nX,
                                               const BitmapColor& rBitmapColor)
{
    pScanline = pScanline + (nX << 2);
    *pScanline++ = 0xFF;
    *pScanline++ = rBitmapColor.GetBlue();
    *pScanline++ = rBitmapColor.GetGreen();
    *pScanline = rBitmapColor.GetRed();
}

BitmapColor BitmapReadAccess::GetPixelForN32BitTcArgb(ConstScanline pScanline, tools::Long nX)
{
    pScanline = pScanline + nX * 4;

    sal_uInt8 a = *pScanline++;
    sal_uInt8 r = *pScanline++;
    sal_uInt8 g = *pScanline++;
    sal_uInt8 b = *pScanline;

    return BitmapColor(ColorAlpha, vcl::bitmap::unpremultiply(r, a),
                       vcl::bitmap::unpremultiply(g, a), vcl::bitmap::unpremultiply(b, a), a);
}

BitmapColor BitmapReadAccess::GetPixelForN32BitTcXrgb(ConstScanline pScanline, tools::Long nX)
{
    BitmapColor aBitmapColor;

    pScanline = pScanline + (nX << 2) + 1;
    aBitmapColor.SetRed(*pScanline++);
    aBitmapColor.SetGreen(*pScanline++);
    aBitmapColor.SetBlue(*pScanline);

    return aBitmapColor;
}

void BitmapReadAccess::SetPixelForN32BitTcArgb(Scanline pScanline, tools::Long nX,
                                               const BitmapColor& rBitmapColor)
{
    pScanline = pScanline + nX * 4;

    sal_uInt8 alpha = rBitmapColor.GetAlpha();
    *pScanline++ = alpha;
    *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
    *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
    *pScanline = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
}

void BitmapReadAccess::SetPixelForN32BitTcXrgb(Scanline pScanline, tools::Long nX,
                                               const BitmapColor& rBitmapColor)
{
    pScanline = pScanline + (nX << 2);
    *pScanline++ = 0xFF;
    *pScanline++ = rBitmapColor.GetRed();
    *pScanline++ = rBitmapColor.GetGreen();
    *pScanline = rBitmapColor.GetBlue();
}

BitmapColor BitmapReadAccess::GetPixelForN32BitTcBgra(ConstScanline pScanline, tools::Long nX)
{
    pScanline = pScanline + nX * 4;

    sal_uInt8 b = *pScanline++;
    sal_uInt8 g = *pScanline++;
    sal_uInt8 r = *pScanline++;
    sal_uInt8 a = *pScanline;

    return BitmapColor(ColorAlpha, vcl::bitmap::unpremultiply(r, a),
                       vcl::bitmap::unpremultiply(g, a), vcl::bitmap::unpremultiply(b, a), a);
}

BitmapColor BitmapReadAccess::GetPixelForN32BitTcBgrx(ConstScanline pScanline, tools::Long nX)
{
    BitmapColor aBitmapColor;

    pScanline = pScanline + (nX << 2);
    aBitmapColor.SetBlue(*pScanline++);
    aBitmapColor.SetGreen(*pScanline++);
    aBitmapColor.SetRed(*pScanline);

    return aBitmapColor;
}

void BitmapReadAccess::SetPixelForN32BitTcBgra(Scanline pScanline, tools::Long nX,
                                               const BitmapColor& rBitmapColor)
{
    pScanline = pScanline + nX * 4;

    sal_uInt8 alpha = rBitmapColor.GetAlpha();
    *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
    *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
    *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
    *pScanline = alpha;
}

void BitmapReadAccess::SetPixelForN32BitTcBgrx(Scanline pScanline, tools::Long nX,
                                               const BitmapColor& rBitmapColor)
{
    pScanline = pScanline + (nX << 2);
    *pScanline++ = rBitmapColor.GetBlue();
    *pScanline++ = rBitmapColor.GetGreen();
    *pScanline++ = rBitmapColor.GetRed();
    *pScanline = 0xFF;
}

BitmapColor BitmapReadAccess::GetPixelForN32BitTcRgba(ConstScanline pScanline, tools::Long nX)
{
    pScanline = pScanline + nX * 4;

    sal_uInt8 r = *pScanline++;
    sal_uInt8 g = *pScanline++;
    sal_uInt8 b = *pScanline++;
    sal_uInt8 a = *pScanline;

    return BitmapColor(ColorAlpha, vcl::bitmap::unpremultiply(r, a),
                       vcl::bitmap::unpremultiply(g, a), vcl::bitmap::unpremultiply(b, a), a);
}

BitmapColor BitmapReadAccess::GetPixelForN32BitTcRgbx(ConstScanline pScanline, tools::Long nX)
{
    BitmapColor aBitmapColor;

    pScanline = pScanline + (nX << 2);
    aBitmapColor.SetRed(*pScanline++);
    aBitmapColor.SetGreen(*pScanline++);
    aBitmapColor.SetBlue(*pScanline);

    return aBitmapColor;
}

void BitmapReadAccess::SetPixelForN32BitTcRgba(Scanline pScanline, tools::Long nX,
                                               const BitmapColor& rBitmapColor)
{
    pScanline = pScanline + nX * 4;

    sal_uInt8 alpha = rBitmapColor.GetAlpha();
    *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetRed(), alpha);
    *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetGreen(), alpha);
    *pScanline++ = vcl::bitmap::premultiply(rBitmapColor.GetBlue(), alpha);
    *pScanline = alpha;
}

void BitmapReadAccess::SetPixelForN32BitTcRgbx(Scanline pScanline, tools::Long nX,
                                               const BitmapColor& rBitmapColor)
{
    pScanline = pScanline + (nX << 2);
    *pScanline++ = rBitmapColor.GetRed();
    *pScanline++ = rBitmapColor.GetGreen();
    *pScanline++ = rBitmapColor.GetBlue();
    *pScanline = 0xFF;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=91 H=95 G=92

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.