PngWriter.cc 3.83 KB
Newer Older
1
2
#ifdef HAVE_PNG

3
4
5
#include <float.h>
#include <png.h>

6
#include "PngWriter.h"
7
8
#include "Traverse.h"
#include "DOFVector.h"
9
10

namespace AMDiS {
Thomas Witkowski's avatar
Thomas Witkowski committed
11
  int PngWriter::writeFile(std::string filename, int imageType) 
12
  {
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    FUNCNAME("PngWriter::writeFile()");
    
    double minX = DBL_MAX, minY = DBL_MAX;
    double maxX = DBL_MIN, maxY = DBL_MIN;
    
    TraverseStack stack;
    ElInfo *elInfo = stack.traverseFirst(dataCollector->getMesh(), -1, 
					 Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
    double pointdist = min(absteukl(elInfo->getCoord(0), elInfo->getCoord(1)),
			   min(absteukl(elInfo->getCoord(1), elInfo->getCoord(2)),
			       absteukl(elInfo->getCoord(2), elInfo->getCoord(0))));
    while (elInfo) {
      for (int i = 0; i < 3; i++) {
	double x = (elInfo->getCoord(i))[0];
	double y = (elInfo->getCoord(i))[1];
	if (x < minX) minX = x;
	if (x > maxX) maxX = x;
	if (y < minY) minY = y;
	if (y > maxY) maxY = y;
      }

      elInfo = stack.traverseNext(elInfo);
    }

    TEST_EXIT(minX == 0.0 && minY == 0.0)("Only supported for minX = minY = 0.0!\n");
    TEST_EXIT(pointdist > 0.0)("This should not happen!\n");

    int imageX = static_cast<int>(maxX / pointdist) + 1;
    int imageY = static_cast<int>(maxY / pointdist) + 1;

    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 
						  NULL, NULL, NULL);   
    if (!png_ptr)
      return 0;

    png_bytep rowPointers[imageY];
    for (int i = 0; i < imageY; i++) {
50
51
52
//       rowPointers[i] = (png_byte*)png_malloc(png_ptr,
// 					     (imageType == 0 ? imageX : imageX * 3));
      rowPointers[i] = (png_byte*)malloc(sizeof(png_byte) * imageX * 3);
53
    }
Thomas Witkowski's avatar
Thomas Witkowski committed
54
    
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    const BasisFunction* basisFcts = dataCollector->getFeSpace()->getBasisFcts();
    Vector<DegreeOfFreedom> localDofs(3);
    DOFVector<double>* dofvalues = dataCollector->getValues();

    elInfo = stack.traverseFirst(dataCollector->getMesh(), -1,
				 Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
    while (elInfo) {
      basisFcts->getLocalIndicesVec(elInfo->getElement(),
				    dataCollector->getFeSpace()->getAdmin(), 
				    &localDofs);

      for (int i = 0; i < 3; i++) {
	if (imageType == 0) {
	  int indexX = static_cast<int>((elInfo->getCoord(i))[0] / pointdist);
	  int indexY = static_cast<int>((elInfo->getCoord(i))[1] / pointdist);
	  rowPointers[indexY][indexX] = 
	    static_cast<unsigned char>((*dofvalues)[localDofs[i]]);
	} else {
73
	  int indexX = static_cast<int>((elInfo->getCoord(i))[0] / pointdist);
74
	  int indexY = static_cast<int>((elInfo->getCoord(i))[1] / pointdist);
75
76
77
78
	  
	  TEST_EXIT(indexX >= 0 && indexX < imageX)("X-index out of range!");
	  TEST_EXIT(indexY >= 0 && indexY < imageY)("Y-index out of range!");

79
80
81
82
83
	  int value = static_cast<int>((*dofvalues)[localDofs[i]]);

 	  unsigned char r = value % 256;
 	  unsigned char g = (value - r % (256 * 256)) / 256;
 	  unsigned char b = (value - r - g) / (256 * 256);
84
85
86
	  rowPointers[indexY][indexX * 3] = r;
	  rowPointers[indexY][indexX * 3 + 1] = g;
	  rowPointers[indexY][indexX * 3 + 2] = b;
87
88
	}
		 
Thomas Witkowski's avatar
Thomas Witkowski committed
89
	}
90
91

      elInfo = stack.traverseNext(elInfo);
Thomas Witkowski's avatar
Thomas Witkowski committed
92
    }   
93
94
95
96
97
98
99
100
101
102
103

    FILE *fp = fopen(filename.c_str(), "wb");
    TEST_EXIT(fp)("Cannot open file for writing matrix picture file!\n");

    png_infop info_ptr = png_create_info_struct(png_ptr);

    if (!info_ptr) {
       png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
       return 0;
    }

104
105
106
107
    if (setjmp(png_jmpbuf(png_ptr))) {
      return 0;
    }

108
109
110
111
112
113
114
115
116
117
    png_init_io(png_ptr, fp);

    png_set_IHDR(png_ptr, info_ptr, imageX, imageY, 8,
		 (imageType == 0 ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_RGB),
		 PNG_INTERLACE_NONE,
		 PNG_COMPRESSION_TYPE_DEFAULT,
		 PNG_FILTER_TYPE_DEFAULT);

    png_set_rows(png_ptr, info_ptr, rowPointers);

118
    png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL);
119
120
121
122
123
124

    png_destroy_write_struct(&png_ptr, &info_ptr);

    fclose(fp);    

    return 0;
125
126
  }
}
127
128

#endif