source: branches/vtkvis_threaded/PPMWriter.cpp @ 2482

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

initial changes for a threaded version of VtkVis? server.

  • Property svn:eol-style set to native
File size: 2.6 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 <stdlib.h>
13#include <sys/uio.h>
14
15#include "Trace.h"
16#include "PPMWriter.h"
17#include "ResponseQueue.h"
18
19using namespace Rappture::VtkVis;
20
21/**
22 * \brief Writes image data as PPM binary data to the client.
23 *
24 * The PPM binary format is very simple.
25 *
26 *     P6 w h 255\n
27 *     3-byte RGB pixel data.
28 *
29 * The client (using the TkImg library) will do less work to unpack this
30 * format, as opposed to BMP or PNG.
31 *
32 * Note that currently the image data has bottom to top scanlines.  This
33 * routine could be made even simpler (faster) if the image data had top
34 * to bottom scanlines.
35 *
36 * \param[in] fd File descriptor that will be written to
37 * \param[in] cmdName Command name to send (byte length will be appended)
38 * \param[in] data Image data
39 * \param[in] width Width of image in pixels
40 * \param[in] height Height of image in pixels
41 */
42void
43Rappture::VtkVis::writePPM(ResponseQueue *queuePtr, const char *cmdName,
44                           const unsigned char *data, int width, int height)
45{
46#define PPM_MAXVAL 255
47    char header[200];
48
49    TRACE("Entering (%dx%d)\n", width, height);
50    // Generate the PPM binary file header
51    snprintf(header, sizeof(header), "P6 %d %d %d\n", width, height,
52        PPM_MAXVAL);
53
54    size_t headerLength = strlen(header);
55    size_t dataLength = width * height * 3;
56
57    char command[200];
58    snprintf(command, sizeof(command), "%s %lu\n", cmdName,
59             (unsigned long)headerLength + dataLength);
60
61    size_t cmdLength;
62    cmdLength = strlen(command);
63
64    size_t length;
65    unsigned char *mesg;
66
67    length = headerLength + dataLength + cmdLength;
68    mesg = (unsigned char *)malloc(length);
69    if (mesg == NULL) {
70        ERROR("can't allocate %ld bytes for the image message", length);
71        return;
72    }
73    memcpy(mesg, command, cmdLength);
74    memcpy(mesg + cmdLength, header, headerLength);
75
76    size_t bytesPerRow = width * 3;
77    unsigned char *destRowPtr = mesg + length - bytesPerRow;
78    int y;
79    unsigned char *srcRowPtr = const_cast<unsigned char *>(data);
80    for (y = 0; y < height; y++) {
81        memcpy(destRowPtr, srcRowPtr, bytesPerRow);
82        srcRowPtr += bytesPerRow;
83        destRowPtr -= bytesPerRow;
84    }
85
86    Response *responsePtr;
87    responsePtr = new Response(MESG_IMAGE);
88    responsePtr->SetMessage(mesg, length);
89    queuePtr->Enqueue(responsePtr);
90    TRACE("Leaving (%dx%d)\n", width, height);
91}
Note: See TracBrowser for help on using the repository browser.