File: read_vtk_image_data.h

package info (click to toggle)
cgal 6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 144,912 kB
  • sloc: cpp: 810,858; ansic: 208,477; sh: 493; python: 411; makefile: 286; javascript: 174
file content (138 lines) | stat: -rw-r--r-- 5,007 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) 2005-2008  INRIA Sophia-Antipolis (France).
//               2008 GeometryFactory
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL: https://github.com/CGAL/cgal/blob/v6.1/CGAL_ImageIO/include/CGAL/IO/read_vtk_image_data.h $
// $Id: include/CGAL/IO/read_vtk_image_data.h b26b07a1242 $
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s)     : Laurent Rineau, Pierre Alliez

#ifndef CGAL_IO_READ_VTK_IMAGE_DATA_H
#define CGAL_IO_READ_VTK_IMAGE_DATA_H

#include <CGAL/Image_3.h>
#include <CGAL/Image_3_vtk_interface.h>

namespace CGAL {

namespace {

struct VTK_to_ImageIO_type_mapper {
  WORD_KIND wordKind;
  SIGN sign;
  unsigned int wdim;
};

static const VTK_to_ImageIO_type_mapper VTK_to_ImageIO_type[VTK_ID_TYPE] =
  { { WK_UNKNOWN, SGN_UNKNOWN,  0}, //  0=VTK_VOID
    { WK_UNKNOWN, SGN_UNKNOWN,  0}, //  1=VTK_BIT
    { WK_FIXED,   SGN_SIGNED,   1}, //  2=VTK_CHAR
    { WK_FIXED,   SGN_UNSIGNED, 1}, //  3=VTK_UNSIGNED_CHAR
    { WK_FIXED,   SGN_SIGNED,   2}, //  4=VTK_SHORT
    { WK_FIXED,   SGN_UNSIGNED, 2}, //  5=VTK_UNSIGNED_SHORT
    { WK_FIXED,   SGN_SIGNED,   4}, //  6=VTK_INT
    { WK_FIXED,   SGN_UNSIGNED, 4}, //  7=VTK_UNSIGNED_INT
    { WK_FIXED,   SGN_SIGNED,   8}, //  8=VTK_LONG
    { WK_FIXED,   SGN_UNSIGNED, 8}, //  9=VTK_UNSIGNED_LONG
    { WK_FLOAT,   SGN_SIGNED,   4}, // 10=VTK_FLOAT
    { WK_FIXED,   SGN_SIGNED,   8}  // 11=VTK_DOUBLE
 };

} //end anonymous namespace

namespace IO {

inline
Image_3
read_vtk_image_data(vtkImageData* vtk_image, Image_3::Own owning = Image_3::OWN_THE_DATA)
{
  if(!vtk_image)
    return Image_3();

  _image* image = ::_initImage();
  const int* dims = vtk_image->GetDimensions();
  const double* spacing = vtk_image->GetSpacing();
  const double* offset = vtk_image->GetOrigin();
  image->vectMode = VM_SCALAR;
  image->xdim = dims[0];
  image->ydim = dims[1];
  image->zdim = dims[2];
  image->vdim = 1;
  image->vx = (spacing[0] == 0) ? 1 : spacing[0];
  image->vy = (spacing[1] == 0) ? 1 : spacing[1];
  image->vz = (spacing[2] == 0) ? 1 : spacing[2];
  image->tx = static_cast<float>(offset[0]);
  image->ty = static_cast<float>(offset[1]);
  image->tz = static_cast<float>(offset[2]);
  image->endianness = ::_getEndianness();

  int vtk_type = vtk_image->GetScalarType();
  if(vtk_type == VTK_SIGNED_CHAR) vtk_type = VTK_CHAR;
  if(vtk_type < 0 || vtk_type > VTK_DOUBLE) vtk_type = VTK_DOUBLE;
  const VTK_to_ImageIO_type_mapper& imageio_type = VTK_to_ImageIO_type[vtk_type];
  image->wdim = imageio_type.wdim;
  image->wordKind = imageio_type.wordKind;
  image->sign = imageio_type.sign;

  const int cn = vtk_image->GetNumberOfScalarComponents();

  if (!vtk_image->GetPointData() || !vtk_image->GetPointData()->GetScalars()) {
    ::_freeImage(image);
    return Image_3();
  }

  // If there is more than a scalar per point, vtk_image->data is not immediately
  // interpretable in Image_3->data
  CGAL_assertion(owning == Image_3::OWN_THE_DATA || cn == 1);
  CGAL_assertion(vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples() == static_cast<vtkIdType>(image->xdim*image->ydim*image->zdim));

  if(owning == Image_3::OWN_THE_DATA) {
    std::size_t dims_n = image->xdim*image->ydim*image->zdim;
    image->data = ::ImageIO_alloc(dims_n * image->wdim);

    // std::cerr << "GetNumberOfTuples() = " << vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples() << "\n"
    //           << "components = " << cn << "\n"
    //           << "wdim = " << image->wdim << "\n"
    //           << "image->size() = " << dims_n << std::endl;

    if(cn == 1) {
      vtk_image->GetPointData()->GetScalars()->ExportToVoidPointer(image->data);
    } else {
      std::cerr << "Warning: input has " << cn << " components; only the value of the first component will be used." << std::endl;
      CGAL_assertion(cn >= 3); // if it's more than 1, it needs to be at least 3

      // cast the data void pointers to make it possible to do pointer arithmetic
      char* src = static_cast<char*>(vtk_image->GetPointData()->GetScalars()->GetVoidPointer(0));
      char* dest = static_cast<char*>(image->data);

      for(std::size_t i=0; i<dims_n; ++i)
      {
        // multiply by image->wdim because we casted to char* and not the actual data type
        memcpy(dest + image->wdim*i, src + cn*image->wdim*i, image->wdim);

        // Check that we are not discarding useful data (i.e., green & blue are identical to red)
        CGAL_assertion(memcmp(src + cn*image->wdim*i, src + cn*image->wdim*i + image->wdim, image->wdim) == 0);
        CGAL_assertion(memcmp(src + cn*image->wdim*i, src + cn*image->wdim*i + 2*image->wdim, image->wdim) == 0);
      }
    }
  } else {
    image->data = vtk_image->GetPointData()->GetScalars()->GetVoidPointer(0);
  }

  return Image_3(image, owning);
}

} // namespace IO

#ifndef CGAL_NO_DEPRECATED_CODE
using IO::read_vtk_image_data;
#endif

} // namespace CGAL


#endif // CGAL_IO_READ_VTK_IMAGE_DATA_H