Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / source / filter / GraphicNativeTransform.cxx
blob664749790d381f668d577aac4b2489d0b84e6664
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <vcl/GraphicNativeTransform.hxx>
22 #include <vcl/gfxlink.hxx>
23 #include <vcl/graphicfilter.hxx>
24 #include <com/sun/star/uno/Sequence.hxx>
25 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include "jpeg/Exif.hxx"
28 #include "jpeg/JpegTransform.hxx"
30 GraphicNativeTransform::GraphicNativeTransform(Graphic& rGraphic) :
31 mrGraphic(rGraphic)
34 GraphicNativeTransform::~GraphicNativeTransform()
37 bool GraphicNativeTransform::canBeRotated()
39 GfxLink aLink = mrGraphic.GetLink();
41 // Don't allow rotation on animations for now
42 if (mrGraphic.IsAnimated())
44 return false;
47 if ( aLink.GetType() == GFX_LINK_TYPE_NATIVE_JPG
48 || aLink.GetType() == GFX_LINK_TYPE_NATIVE_PNG
49 || aLink.GetType() == GFX_LINK_TYPE_NATIVE_GIF
50 || aLink.GetType() == GFX_LINK_TYPE_NONE)
52 return true;
55 return false;
58 bool GraphicNativeTransform::rotate(sal_uInt16 aInputRotation)
60 // Rotation can be between 0 and 3600
61 sal_uInt16 aRotation = aInputRotation % 3600;
63 if (aRotation == 0)
65 return true; // No rotation is needed
67 else if (aRotation != 900 && aRotation != 1800 && aRotation != 2700)
69 return false;
72 GfxLink aLink = mrGraphic.GetLink();
73 if ( aLink.GetType() == GFX_LINK_TYPE_NATIVE_JPG )
75 return rotateJPEG(aRotation);
77 else if ( aLink.GetType() == GFX_LINK_TYPE_NATIVE_PNG )
79 return rotateGeneric(aRotation, OUString("png"));
81 else if ( aLink.GetType() == GFX_LINK_TYPE_NATIVE_GIF )
83 return rotateGeneric(aRotation, OUString("gif"));
85 else if ( aLink.GetType() == GFX_LINK_TYPE_NONE )
87 return rotateBitmapOnly(aRotation);
89 return false;
92 bool GraphicNativeTransform::rotateBitmapOnly(sal_uInt16 aRotation)
94 if (mrGraphic.IsAnimated())
96 return false;
99 BitmapEx aBitmap = mrGraphic.GetBitmapEx();
100 aBitmap.Rotate(aRotation, COL_BLACK);
101 mrGraphic = aBitmap;
103 return true;
106 bool GraphicNativeTransform::rotateGeneric(sal_uInt16 aRotation, const OUString& aType)
108 // Can't rotate animations yet
109 if (mrGraphic.IsAnimated())
111 return false;
114 SvMemoryStream aStream;
116 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
118 css::uno::Sequence< css::beans::PropertyValue > aFilterData( 3 );
119 aFilterData[ 0 ].Name = "Interlaced";
120 aFilterData[ 0 ].Value <<= (sal_Int32) 0;
121 aFilterData[ 1 ].Name = "Compression";
122 aFilterData[ 1 ].Value <<= (sal_Int32) 9;
123 aFilterData[ 2 ].Name = "Quality";
124 aFilterData[ 2 ].Value <<= (sal_Int32) 90;
126 sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName( aType );
128 BitmapEx aBitmap = mrGraphic.GetBitmapEx();
129 aBitmap.Rotate(aRotation, COL_BLACK);
130 rFilter.ExportGraphic( aBitmap, OUString( "none" ), aStream, nFilterFormat, &aFilterData );
132 aStream.Seek( STREAM_SEEK_TO_BEGIN );
134 Graphic aGraphic;
135 rFilter.ImportGraphic( aGraphic, OUString("import"), aStream );
137 mrGraphic = aGraphic;
138 return true;
141 bool GraphicNativeTransform::rotateJPEG(sal_uInt16 aRotation)
143 BitmapEx aBitmap = mrGraphic.GetBitmapEx();
145 if (aBitmap.GetSizePixel().Width() % 16 != 0 ||
146 aBitmap.GetSizePixel().Height() % 16 != 0 )
148 rotateGeneric(aRotation, OUString("png"));
150 else
152 GfxLink aLink = mrGraphic.GetLink();
154 SvMemoryStream aSourceStream;
155 aSourceStream.Write(aLink.GetData(), aLink.GetDataSize());
156 aSourceStream.Seek( STREAM_SEEK_TO_BEGIN );
158 Orientation aOrientation = TOP_LEFT;
160 Exif exif;
161 if ( exif.read(aSourceStream) )
163 aOrientation = exif.getOrientation();
166 SvMemoryStream aTargetStream;
167 JpegTransform tranform(aSourceStream, aTargetStream);
168 tranform.setRotate(aRotation);
169 tranform.perform();
171 aTargetStream.Seek( STREAM_SEEK_TO_BEGIN );
173 // Reset orientation in exif if needed
174 if ( exif.hasExif() && aOrientation != TOP_LEFT)
176 exif.setOrientation(TOP_LEFT);
177 exif.write(aTargetStream);
180 aTargetStream.Seek( STREAM_SEEK_TO_BEGIN );
182 Graphic aGraphic;
183 GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
184 rFilter.ImportGraphic( aGraphic, OUString("import"), aTargetStream );
185 mrGraphic = aGraphic;
188 return true;
191 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */