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

Last change on this file since 2120 was 2120, checked in by gah, 13 years ago
File size: 2.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: ?
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 */
34void
35Rappture::VtkVis::writePPM(int fd, const char *cmdName, const unsigned char *data,
36                           int width, int height)
37{
38#define PPM_MAXVAL 255
39    char header[200];
40
41    TRACE("Entering (%dx%d)\n", width, height);
42    // Generate the PPM binary file header
43    snprintf(header, sizeof(header), "P6 %d %d %d\n", width, height, PPM_MAXVAL);
44
45    size_t headerLength = strlen(header);
46    size_t dataLength = width * height * 3;
47
48    char command[200];
49    snprintf(command, sizeof(command), "%s %lu\n", cmdName,
50             (unsigned long)headerLength + dataLength);
51
52    size_t nRecs = height + 2;
53
54    struct iovec *iov;
55    iov = (struct iovec *)malloc(sizeof(struct iovec) * nRecs);
56
57    // Write the command, then the image header and data.
58    // Command
59    iov[0].iov_base = command;
60    iov[0].iov_len = strlen(command);
61    // Header of image data
62    iov[1].iov_base = header;
63    iov[1].iov_len = headerLength;
64
65    // Image data
66    size_t bytesPerRow = width * 3;
67    int y;
68    unsigned char *srcRowPtr = const_cast<unsigned char *>(data);
69    for (y = height + 1; y >= 2; y--) {
70        iov[y].iov_base = srcRowPtr;
71        iov[y].iov_len = bytesPerRow;
72        srcRowPtr += bytesPerRow;
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}
Note: See TracBrowser for help on using the repository browser.