source: trunk/packages/vizservers/vtkvis/TGAWriter.cpp @ 2260

Last change on this file since 2260 was 2260, checked in by ldelgass, 13 years ago

New heightmap command/object in vtkvis server - contour plot with vertical
displacement. Also initial work on supporting additional data set types
such as point clouds.

  • Property svn:eol-style set to native
File size: 4.1 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2011, Purdue Research Foundation
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#include <cstdio>
9#include <cstdlib>
10#include <cstring>
11#include <cerrno>
12#include <sys/uio.h>
13
14#include <iostream>
15#include <fstream>
16
17#include "TGAWriter.h"
18#include "Trace.h"
19
20/**
21 * \brief Writes image command + data to supplied file descriptor.
22 *
23 * The image data must be supplied in BGR(A) order with bottom to
24 * top scanline ordering.
25 *
26 * \param[in] fd File descriptor that will be written to
27 * \param[in] cmdName Command name to send (byte length will be appended)
28 * \param[in] data Image data
29 * \param[in] width Width of image in pixels
30 * \param[in] height Height of image in pixels
31 * \param[in] bytesPerPixel Should be 3 or 4, depending on alpha
32 */
33void
34Rappture::VtkVis::writeTGA(int fd, const char *cmdName,
35                           const unsigned char *data,
36                           int width, int height,
37                           int bytesPerPixel)
38{
39    TRACE("(%dx%d)\n", width, height);
40
41    size_t headerLength = 18;
42
43    char header[headerLength];
44    memset(header, 0, headerLength);
45    header[2] = (char)2;  // image type (2 = uncompressed true-color)
46    header[12] = (char)width;
47    header[13] = (char)(width >> 8);
48    header[14] = (char)height;
49    header[15] = (char)(height >> 8);
50    header[16] = (char)(bytesPerPixel*8); // bits per pixel
51
52    size_t dataLength = width * height * bytesPerPixel;
53
54    char command[200];
55    snprintf(command, sizeof(command), "%s %lu\n", cmdName,
56             (unsigned long)headerLength + dataLength);
57
58    size_t nRecs = 3;
59
60    struct iovec *iov;
61    iov = (struct iovec *)malloc(sizeof(struct iovec) * nRecs);
62
63    // Write the command, then the image header and data.
64    // Command
65    iov[0].iov_base = command;
66    iov[0].iov_len = strlen(command);
67    // Header of image data
68    iov[1].iov_base = header;
69    iov[1].iov_len = headerLength;
70    // Image data **must be BGR(A)!**
71    iov[2].iov_base = const_cast<unsigned char *>(data);
72    iov[2].iov_len = dataLength;
73
74    if (writev(fd, iov, nRecs) < 0) {
75        ERROR("write failed: %s\n", strerror(errno));
76    }
77    free(iov);
78
79    TRACE("Leaving (%dx%d)\n", width, height);
80}
81
82/**
83 * \brief Writes image data to supplied file name
84 *
85 * The image data must be supplied with bottom to top
86 * scanline ordering.  Source data should have BGR(A)
87 * ordering, unless srcIsRGB is true, in which case
88 * the source data will be converted from RGB(A) to
89 * BGR(A).  Note that this is slow and it is better
90 * to pass in BGR(A) data.
91 *
92 * \param[in] filename Path to file that will be written
93 * \param[in] imgData Image data
94 * \param[in] width Width of image in pixels
95 * \param[in] height Height of image in pixels
96 * \param[in] bytesPerPixel Should be 3 or 4, depending on alpha
97 * \param[in] srcIsRGB If true source data will be re-ordered
98 */
99void
100Rappture::VtkVis::writeTGAFile(const char *filename,
101                               const unsigned char *imgData,
102                               int width, int height,
103                               int bytesPerPixel,
104                               bool srcIsRGB)
105{
106    TRACE("%s (%dx%d)\n", filename, width, height);
107
108    std::ofstream outfile(filename, std::ios::out | std::ios::binary | std::ios::trunc);
109    char header[18];
110    memset(header, 0, 18);
111    header[2] = (char)2;  // image type (2 = uncompressed true-color)
112    header[12] = (char)width;
113    header[13] = (char)(width >> 8);
114    header[14] = (char)height;
115    header[15] = (char)(height >> 8);
116    header[16] = (char)(bytesPerPixel*8); // bits per pixel
117
118    outfile.write(header, sizeof(header));
119
120    if (!srcIsRGB) {
121        outfile.write((const char *)imgData, width * height * bytesPerPixel);
122    } else {
123        // RGB(A) -> BGR(A)
124        for (int i = 0; i < width * height; i++) {
125            outfile << imgData[i*bytesPerPixel+2]
126                    << imgData[i*bytesPerPixel+1]
127                    << imgData[i*bytesPerPixel];
128            if (bytesPerPixel == 4) {
129                outfile << imgData[i*bytesPerPixel+3];
130            }
131        }
132    }
133
134    outfile.close();
135}
Note: See TracBrowser for help on using the repository browser.