source: branches/blt4/packages/vizservers/vtkvis/PPMWriter.cpp @ 2302

Last change on this file since 2302 was 2302, checked in by gah, 13 years ago

update from trunk

File size: 2.4 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2011, Purdue Research Foundation
4 *
5 * Author: ?
6 */
7
8#include <cstdio>
9#include <cstdlib>
10#include <cstring>
11#include <cerrno>
12#include <sys/uio.h>
13
14#include "PPMWriter.h"
15#include "Trace.h"
16
17using namespace Rappture::VtkVis;
18
19/**
20 * \brief Writes image data as PPM binary data to the client.
21 *
22 * The PPM binary format is very simple.
23 *
24 *     P6 w h 255\n
25 *     3-byte RGB pixel data.
26 *
27 * The client (using the TkImg library) will do less work to unpack this
28 * format, as opposed to BMP or PNG.
29 *
30 * Note that currently the image data has bottom to top scanlines.  This
31 * routine could be made even simpler (faster) if the image data had top
32 * to bottom scanlines.
33 *
34 * \param[in] fd File descriptor that will be written to
35 * \param[in] cmdName Command name to send (byte length will be appended)
36 * \param[in] data Image data
37 * \param[in] width Width of image in pixels
38 * \param[in] height Height of image in pixels
39 */
40void
41Rappture::VtkVis::writePPM(int fd, const char *cmdName, const unsigned char *data,
42                           int width, int height)
43{
44#define PPM_MAXVAL 255
45    char header[200];
46
47    TRACE("Entering (%dx%d)\n", width, height);
48    // Generate the PPM binary file header
49    snprintf(header, sizeof(header), "P6 %d %d %d\n", width, height, PPM_MAXVAL);
50
51    size_t headerLength = strlen(header);
52    size_t dataLength = width * height * 3;
53
54    char command[200];
55    snprintf(command, sizeof(command), "%s %lu\n", cmdName,
56             (unsigned long)headerLength + dataLength);
57
58    size_t nRecs = height + 2;
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
71    // Image data
72    size_t bytesPerRow = width * 3;
73    int y;
74    unsigned char *srcRowPtr = const_cast<unsigned char *>(data);
75    for (y = height + 1; y >= 2; y--) {
76        iov[y].iov_base = srcRowPtr;
77        iov[y].iov_len = bytesPerRow;
78        srcRowPtr += bytesPerRow;
79    }
80    if (writev(fd, iov, nRecs) < 0) {
81        ERROR("write failed: %s\n", strerror(errno));
82    }
83    free(iov);
84
85    TRACE("Leaving (%dx%d)\n", width, height);
86}
Note: See TracBrowser for help on using the repository browser.