Salome HOME
Initial version
[modules/hydro.git] / src / HYDROData / HYDROData_Image.cxx
1 #include <HYDROData_Image.h>
2 #include <HYDROData_Iterator.h>
3
4 #include <TDataStd_RealArray.hxx>
5 #include <TDataStd_IntegerArray.hxx>
6 #include <TDataStd_ByteArray.hxx>
7 #include <TDataStd_ReferenceList.hxx>
8 #include <TDF_ListIteratorOfLabelList.hxx>
9
10 IMPLEMENT_STANDARD_HANDLE(HYDROData_Image, HYDROData_Object)
11 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Image, HYDROData_Object)
12
13 HYDROData_Image::HYDROData_Image()
14 {
15 }
16
17 HYDROData_Image::~HYDROData_Image()
18 {
19 }
20
21 void HYDROData_Image::SetImage(const QImage& theImage)
22 {
23   if (theImage.isNull()) {
24     // for empty image remove all previously stored attributes
25     myLab.ForgetAttribute(TDataStd_IntegerArray::GetID());
26     myLab.ForgetAttribute(TDataStd_ByteArray::GetID());
27     return;
28   }
29   // store width, height, bytes per line and format in integer array 
30   Handle(TDataStd_IntegerArray) aParams;
31   if (!myLab.FindAttribute(TDataStd_IntegerArray::GetID(), aParams)) {
32     aParams = TDataStd_IntegerArray::Set(myLab, 1, 4);
33   }
34   aParams->SetValue(1, theImage.width());
35   aParams->SetValue(2, theImage.height());
36   aParams->SetValue(3, theImage.bytesPerLine());
37   aParams->SetValue(4, (int)(theImage.format()));
38   // store data of image in byte array
39   Handle(TDataStd_ByteArray) aData;
40   int aLen = theImage.byteCount();
41   if (!myLab.FindAttribute(TDataStd_ByteArray::GetID(), aData)) {
42     aData = TDataStd_ByteArray::Set(myLab, 1, aLen);
43   }
44   // copy bytes one by one
45   const uchar* aBits = theImage.bits();
46   if (aData->Length() != aLen) {
47     Handle(TColStd_HArray1OfByte) aNewData = new TColStd_HArray1OfByte(1, aLen);
48     for(int a = 0; a < aLen; a++)
49       aNewData->SetValue(a + 1, aBits[a]);
50     aData->ChangeArray(aNewData);
51   } else {
52     for(int a = 0; a < aLen; a++)
53       aData->SetValue(a + 1, aBits[a]);
54   }
55
56 }
57
58 QImage HYDROData_Image::Image()
59 {
60   Handle(TDataStd_IntegerArray) aParams;
61   Handle(TDataStd_ByteArray) aData;
62   if (!myLab.FindAttribute(TDataStd_IntegerArray::GetID(), aParams) ||
63       !myLab.FindAttribute(TDataStd_ByteArray::GetID(), aData))
64     return QImage(); // return empty image if there is no array
65   /*
66   // make uchar array one by one
67   int aLen = aData->Upper();
68   uchar* anArray = new uchar[aLen];
69   for(int a = 0; a < aLen; a++)
70     anArray[a] = aData->Value(a + 1);
71   // recreate image from integer parameters and array of bytes
72   QImage aResult(anArray, aParams->Value(1), aParams->Value(2),
73                  aParams->Value(3), QImage::Format(aParams->Value(4)));
74   delete [] anArray; <- this is wrong, because QImage references to this array
75   */
76   uchar* anArray = (uchar*)(void*)(&(aData->InternalArray()->ChangeArray1().ChangeValue(1)));
77   QImage aResult(anArray, aParams->Value(1), aParams->Value(2),
78                  aParams->Value(3), QImage::Format(aParams->Value(4)));
79
80   return aResult;
81 }
82
83 void HYDROData_Image::SetTrsf(const QTransform& theTrsf)
84 {
85   // locate 9 coeffs of matrix into the real array
86   Handle(TDataStd_RealArray) anArray;
87   if (!myLab.FindAttribute(TDataStd_RealArray::GetID(), anArray)) {
88     if (theTrsf.isIdentity()) return; // no need to store identity transformation
89     anArray = TDataStd_RealArray::Set(myLab, 1, 9);
90   }
91   anArray->SetValue(1, theTrsf.m11());
92   anArray->SetValue(2, theTrsf.m12());
93   anArray->SetValue(3, theTrsf.m13());
94   anArray->SetValue(4, theTrsf.m21());
95   anArray->SetValue(5, theTrsf.m22());
96   anArray->SetValue(6, theTrsf.m23());
97   anArray->SetValue(7, theTrsf.m31());
98   anArray->SetValue(8, theTrsf.m32());
99   anArray->SetValue(9, theTrsf.m33());
100 }
101
102 QTransform HYDROData_Image::Trsf()
103 {
104   // get 9 coeffs of matrix from the real array
105   Handle(TDataStd_RealArray) anArray;
106   if (!myLab.FindAttribute(TDataStd_RealArray::GetID(), anArray))
107     return QTransform(); // return identity if there is no array
108   QTransform aTrsf(
109     anArray->Value(1), anArray->Value(2), anArray->Value(3), 
110     anArray->Value(4), anArray->Value(5), anArray->Value(6), 
111     anArray->Value(7), anArray->Value(8), anArray->Value(9));
112   return aTrsf;
113 }
114
115 void HYDROData_Image::AppendReference(Handle(HYDROData_Image) theReferenced)
116 {
117   Handle(TDataStd_ReferenceList) aRefs;
118   if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs))
119     aRefs = TDataStd_ReferenceList::Set(myLab);
120   aRefs->Append(theReferenced->Label());
121 }
122
123 int HYDROData_Image::NbReferences()
124 {
125   Handle(TDataStd_ReferenceList) aRefs;
126   if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs))
127     return 0;
128   return aRefs->Extent();
129 }
130
131 Handle(HYDROData_Image) HYDROData_Image::Reference(const int theIndex) const
132 {
133   Handle(TDataStd_ReferenceList) aRefs;
134   if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs))
135     return Handle(HYDROData_Image)();
136   if (theIndex < 0 || theIndex >= aRefs->Extent())
137     return Handle(HYDROData_Image)();
138
139   TDF_ListIteratorOfLabelList anIter(aRefs->List());
140   for(int anIndex = 0; anIndex != theIndex; anIter.Next(), anIndex++);
141   const TDF_Label& aRefLab = anIter.Value();
142   return Handle(HYDROData_Image)::DownCast(HYDROData_Iterator::Object(aRefLab));
143 }
144
145 void HYDROData_Image::ChangeReference(
146     const int theIndex, Handle(HYDROData_Image) theReferenced)
147 {
148   Handle(TDataStd_ReferenceList) aRefs;
149   if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs))
150     aRefs = TDataStd_ReferenceList::Set(myLab);
151   if (theIndex >= aRefs->Extent()) { // for too big index append it just to the end
152     AppendReference(theReferenced);
153   } else { // remove and insert new
154     TDF_ListIteratorOfLabelList anIter(aRefs->List());
155     int anIndex = 0;
156     for(; anIndex != theIndex; anIter.Next(), anIndex++);
157     const TDF_Label& aRemovedLab = anIter.Value();
158     anIter.Next();
159     aRefs->Remove(aRemovedLab);
160     if (anIter.More()) 
161       aRefs->InsertBefore(theReferenced->Label(), anIter.Value());
162     else 
163       aRefs->Append(theReferenced->Label());
164   }
165 }
166
167 void HYDROData_Image::RemoveReference(const int theIndex)
168 {
169   Handle(TDataStd_ReferenceList) aRefs;
170   if (!myLab.FindAttribute(TDataStd_ReferenceList::GetID(), aRefs))
171     return; // no references, nothing to remove
172   if (aRefs->Extent() == 1 && theIndex == 0) { // remove all if only one
173     ClearReferences();
174     return;
175   }
176   TDF_ListIteratorOfLabelList anIter(aRefs->List());
177   int anIndex = 0;
178   for(; anIndex != theIndex && anIter.More(); anIter.Next(), anIndex++);
179   if (anIter.More())
180     aRefs->Remove(anIter.Value());
181 }
182
183 void HYDROData_Image::ClearReferences()
184 {
185   myLab.ForgetAttribute(TDataStd_ReferenceList::GetID());
186 }