*** empty log message ***

svn path=/trunk/boinc/; revision=4800
This commit is contained in:
David Anderson 2004-12-09 00:46:07 +00:00
parent 43fea339c2
commit 289241c87b
14 changed files with 565 additions and 57 deletions

View File

@ -12,6 +12,8 @@ graphics_api_files = \
graphics_api.C \
reduce.C \
gutil.C \
bmplib.C \
tgalib.C \
graphics_data.h \
reduce.h \
x_opengl.h \

186
api/bmplib.C Normal file
View File

@ -0,0 +1,186 @@
#ifdef _WIN32
#include "boinc_win.h"
#endif
#include "bmplib.h"
// Returns true for success -- false otherwise
bool DIB_BITMAP::set_size(int width, int height, int channels)
{
// If DIB_BITMAP has already been set -- clear it out first
FreeDIB_BMP();
// Create a temporary compatible device context
HDC temp_hdc = CreateCompatibleDC(NULL);
// Error Check
if(!temp_hdc)
return false;
bmp_width = width; // Set the width
bmp_height = height; // Set the height
bmp_channels = channels; // Set the channels (3 == 24-bit, 4 == 32-bit)
// Set stride -- The stride is the TRUE number of bytes in a line of pixels
// Windows makes all the .bmps DWORD aligned (divisible evenly by 4)
// So if you bitmap say was 103x103 pixels, Windows would add 1 "padding byte" to it
// so in memory it would be 104x103 pixels. The "padding bytes" do not get blit (drawn)
// to the screen, they're just there so again everything is DWORD aligned which makes
// blitting (drawing to the screen) easier for the OS
bmp_stride = bmp_width * bmp_channels;
while((bmp_stride % 4) != 0) // Ensure bmp_stride is DWORD aligned
bmp_stride++;
BITMAPINFO bmp_info = {0};
// Initialize the parameters that we care about
bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmp_info.bmiHeader.biWidth = width;
bmp_info.bmiHeader.biHeight = height;
bmp_info.bmiHeader.biPlanes = 1; // Always equal 1
bmp_info.bmiHeader.biBitCount = channels * 8;
bmp_info.bmiHeader.biCompression = BI_RGB; // No compression
bmp_info.bmiHeader.biClrUsed = 0; // Always equals 0 with a 24 or 32-bit .bmp
// Create a DIBSection -- This returns us two things, an HBITMAP handle and
// a memory pointer (pointer to the pixels) in surface_bits
hbitmap = CreateDIBSection(temp_hdc, &bmp_info, DIB_RGB_COLORS,
(void**)&surface_bits, 0, 0);
// Release our temporary HDC
DeleteDC(temp_hdc);
// Error Check -- Make sure the call to CreateDIBSection() DID NOT fail
if(!hbitmap)
return false;
return true; // We're sized :)
} // end of set_size(int width, int height, int channels)
bool DIB_BITMAP::loadBMP(const char *file_name)
{
// If DIB_BITMAP has already been set -- clear it out first
FreeDIB_BMP();
// Error Check -- Make sure they passed in a valid file name
if(!file_name)
return false;
FILE *bmp_file = fopen(file_name, "rb");
// Error Check -- Make sure the file could be opened
if(!bmp_file)
return false;
BITMAPFILEHEADER bmp_fileheader;
// Read the BITMAPFILEHEADER
if(!fread(&bmp_fileheader, sizeof(BITMAPFILEHEADER), 1, bmp_file))
{
fclose(bmp_file);
return false;
}
// Check the type field to make sure we have a .bmp file
if(memcmp(&bmp_fileheader.bfType, "BM", 2))
{
fclose(bmp_file);
return false;
}
BITMAPINFOHEADER bmp_infoheader;
// Read the BITMAPINFOHEADER.
if(!fread(&bmp_infoheader, sizeof(BITMAPINFOHEADER), 1, bmp_file))
{
fclose(bmp_file);
return false;
}
// We only support 24-bit and 32-bit .bmps so make sure that's what we have
if((bmp_infoheader.biBitCount != 24) && (bmp_infoheader.biBitCount != 32))
{
fclose(bmp_file);
return false;
}
// Set the size of our DIB_BITMAP, once we do this we're ready to store the pixel
// data in it
if(set_size(bmp_infoheader.biWidth,bmp_infoheader.biHeight,bmp_infoheader.biBitCount / 8) == false)
{
fclose(bmp_file);
return false;
}
// Jump to the location where the pixel data is stored
if(fseek(bmp_file, bmp_fileheader.bfOffBits, SEEK_SET))
{
fclose(bmp_file);
return false;
}
unsigned int bytesPerLine = bmp_width * bmp_channels; // Bytes per line (number of bytes
// in a scan line)
// Calculate how many "padding" bytes there are -- WE DO NOT want to read in the
// padding bytes (we will just skip over those)
// **Remember** Windows adds padding bytes to ensure ALL .bmps are DWORD aligned
// (divisible evenly by 4)
unsigned int padding = bmp_stride - bytesPerLine;
// Loop over all the scan lines (all the rows of pixels in the image)
for(int y = bmp_height-1; y >= 0; y--)
{
// Get the "current" line pointer
uchar *LinePtr = getLinePtr(y);
// Read the precise number of bytes that the scan line requires into the bitmap
if(!fread(LinePtr, bytesPerLine, 1, bmp_file))
{
fclose(bmp_file);
return false;
}
// Skip over any padding bytes.
if(fseek(bmp_file, padding, SEEK_CUR))
{
fclose(bmp_file);
return false;
}
} // end of for (int y = 0; y < bmp_infoheader.biHeight; y++)
fclose(bmp_file);
return true; // If we get here .bmp was read in successfully
} // end of loadBMP(char *file_name, HDC hdc)
// Returns the address in memory of the specified line. This gives you a pointer to at least
// width * channels bytes. Lines are numbered such that when the bitmap
// is displayed line zero is at the top.
uchar* DIB_BITMAP::getLinePtr(int which_line)
{
return (surface_bits + bmp_stride * which_line);
}
// Release the memory
void DIB_BITMAP::FreeDIB_BMP()
{
// If we created an HBITMAP, delete it
if(hbitmap)
DeleteObject(hbitmap);
// Zero out all data associated with DIB_BITMAP
hbitmap = NULL;
surface_bits = NULL;
bmp_width = bmp_height = bmp_channels = bmp_stride = 0;
return;
}
// Deconstructor
DIB_BITMAP::~DIB_BITMAP() { FreeDIB_BMP(); }

57
api/bmplib.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef BITMAP_CLASS_H
#define BITMAP_CLASS_H
typedef unsigned char uchar; // We're lazy so typedef "unsigned char" as "uchar"
// We will use this class to load 24 and 32-bit .bmp for us
class DIB_BITMAP
{
public:
// Constructor() -- Zero's out DIB_BITMAP
DIB_BITMAP():hbitmap(NULL),surface_bits(NULL),bmp_width(0),bmp_height(0),
bmp_channels(0),bmp_stride(0) { GdiFlush(); /* Guarantee that writing to
DIB_BITMAP is okay */ }
// Data Access Functions ************
inline int get_width() const { return bmp_width; }
inline int get_height() const { return bmp_height; }
inline int get_channels() const { return bmp_channels; }
inline int get_stride() const { return bmp_stride; }
// ****** End of Data Access Functions
// Creates a "empty" DIB_BITMAP with the "traits" of the parameters passed in
// Returns true for success -- false otherwise
// If set_size is called on a DIB_BITMAP that already has memory associated with it
// that memory is freed and the new size is implemented
bool set_size(int width, int height, int channels);
// Loads a bmp with specified file_name -- Returns true on success, false otherwise
// If loadBMP() is called on a DIB_BITMAP that already has memory associated with
// it, that memory is freed and the .bmp is loaded
bool loadBMP(const char *file_name);
uchar* getLinePtr(int which_line); // returns a pointer to the line passed in
// Deconstructor();
~DIB_BITMAP();
private:
int bmp_width; // The width of the bitmap
int bmp_height; // The height of the bitmap
int bmp_channels; // How many channels is the bitmap (3 == 24-bit, 4 == 32-bit)
int bmp_stride; // The TRUE number of bytes in a scan line (in a line of pixels
// in memory)
HBITMAP hbitmap; // This will be the handle to our bitmap
uchar *surface_bits; // This is a pointer to the actual pixels of the bitmap
void FreeDIB_BMP(); // Frees all memory associated with DIB_BITMAP
};
#endif

239
api/tgalib.C Normal file
View File

@ -0,0 +1,239 @@
#include "tgalib.h"
tImageTGA *LoadTGA(const char *filename)
{
tImageTGA *pImageData = NULL; // This stores our important image data
WORD width = 0, height = 0; // The dimensions of the image
byte length = 0; // The length in bytes to the pixels
byte imageType = 0; // The image type (RLE, RGB, Alpha...)
byte bits = 0; // The bits per pixel for the image (16, 24, 32)
FILE *pFile = NULL; // The file pointer
int channels = 0; // The channels of the image (3 = RGA : 4 = RGBA)
int stride = 0; // The stride (channels * width)
int i = 0; // A counter
// This function loads in a TARGA (.TGA) file and returns its data to be
// used as a texture or what have you. This currently loads in a 16, 24
// and 32-bit targa file, along with RLE compressed files. Eventually you
// will want to do more error checking to make it more robust. This is
// also a perfect start to go into a modular class for an engine.
// Basically, how it works is, you read in the header information, then
// move your file pointer to the pixel data. Before reading in the pixel
// data, we check to see the if it's an RLE compressed image. This is because
// we will handle it different. If it isn't compressed, then we need another
// check to see if we need to convert it from 16-bit to 24 bit. 24-bit and
// 32-bit textures are very similar, so there's no need to do anything special.
// We do, however, read in an extra bit for each color.
// Open a file pointer to the targa file and check if it was found and opened
if((pFile = fopen(filename, "rb")) == NULL)
{
return NULL;
}
// Allocate the structure that will hold our eventual image data (must free it!)
pImageData = (tImageTGA*)malloc(sizeof(tImageTGA));
// Read in the length in bytes from the header to the pixel data
fread(&length, sizeof(byte), 1, pFile);
// Jump over one byte
fseek(pFile,1,SEEK_CUR);
// Read in the imageType (RLE, RGB, etc...)
fread(&imageType, sizeof(byte), 1, pFile);
// Skip past general information we don't care about
fseek(pFile, 9, SEEK_CUR);
// Read the width, height and bits per pixel (16, 24 or 32)
fread(&width, sizeof(WORD), 1, pFile);
fread(&height, sizeof(WORD), 1, pFile);
fread(&bits, sizeof(byte), 1, pFile);
// Now we move the file pointer to the pixel data
fseek(pFile, length + 1, SEEK_CUR);
// Check if the image is RLE compressed or not
if(imageType != TGA_RLE)
{
// Check if the image is a 24 or 32-bit image
if(bits == 24 || bits == 32)
{
// Calculate the channels (3 or 4) - (use bits >> 3 for more speed).
// Next, we calculate the stride and allocate enough memory for the pixels.
channels = bits / 8;
stride = channels * width;
pImageData->data = new unsigned char[stride * height];
// Load in all the pixel data line by line
for(int y = 0; y < height; y++)
{
// Store a pointer to the current line of pixels
unsigned char *pLine = &(pImageData->data[stride * y]);
// Read in the current line of pixels
fread(pLine, stride, 1, pFile);
// Go through all of the pixels and swap the B and R values since TGA
// files are stored as BGR instead of RGB (or use GL_BGR_EXT verses GL_RGB)
for(i = 0; i < stride; i += channels)
{
int temp = pLine[i];
pLine[i] = pLine[i + 2];
pLine[i + 2] = temp;
}
}
}
// Check if the image is a 16 bit image (RGB stored in 1 unsigned short)
else if(bits == 16)
{
unsigned short pixels = 0;
int r=0, g=0, b=0;
// Since we convert 16-bit images to 24 bit, we hardcode the channels to 3.
// We then calculate the stride and allocate memory for the pixels.
channels = 3;
stride = channels * width;
pImageData->data = new unsigned char[stride * height];
// Load in all the pixel data pixel by pixel
for(int i = 0; i < width*height; i++)
{
// Read in the current pixel
fread(&pixels, sizeof(unsigned short), 1, pFile);
// To convert a 16-bit pixel into an R, G, B, we need to
// do some masking and such to isolate each color value.
// 0x1f = 11111 in binary, so since 5 bits are reserved in
// each unsigned short for the R, G and B, we bit shift and mask
// to find each value. We then bit shift up by 3 to get the full color.
b = (pixels & 0x1f) << 3;
g = ((pixels >> 5) & 0x1f) << 3;
r = ((pixels >> 10) & 0x1f) << 3;
// This essentially assigns the color to our array and swaps the
// B and R values at the same time.
pImageData->data[i * 3 + 0] = r;
pImageData->data[i * 3 + 1] = g;
pImageData->data[i * 3 + 2] = b;
}
}
// Else return a NULL for a bad or unsupported pixel format
else
return NULL;
}
// Else, it must be Run-Length Encoded (RLE)
else
{
// First, let me explain real quickly what RLE is.
// For further information, check out Paul Bourke's intro article at:
// http://astronomy.swin.edu.au/~pbourke/dataformats/rle/
//
// Anyway, we know that RLE is a basic type compression. It takes
// colors that are next to each other and then shrinks that info down
// into the color and a integer that tells how much of that color is used.
// For instance:
// aaaaabbcccccccc would turn into a5b2c8
// Well, that's fine and dandy and all, but how is it down with RGB colors?
// Simple, you read in an color count (rleID), and if that number is less than 128,
// it does NOT have any optimization for those colors, so we just read the next
// pixels normally. Say, the color count was 28, we read in 28 colors like normal.
// If the color count is over 128, that means that the next color is optimized and
// we want to read in the same pixel color for a count of (colorCount - 127).
// It's 127 because we add 1 to the color count, as you'll notice in the code.
// Create some variables to hold the rleID, current colors read, channels, & stride.
byte rleID = 0;
int colorsRead = 0;
channels = bits / 8;
stride = channels * width;
// Next we want to allocate the memory for the pixels and create an array,
// depending on the channel count, to read in for each pixel.
pImageData->data = new unsigned char[stride * height];
byte *pColors = new byte [channels];
// Load in all the pixel data
while(i < width*height)
{
// Read in the current color count + 1
fread(&rleID, sizeof(byte), 1, pFile);
// Check if we don't have an encoded string of colors
if(rleID < 128)
{
// Increase the count by 1
rleID++;
// Go through and read all the unique colors found
while(rleID)
{
// Read in the current color
fread(pColors, sizeof(byte) * channels, 1, pFile);
// Store the current pixel in our image array
pImageData->data[colorsRead + 0] = pColors[2];
pImageData->data[colorsRead + 1] = pColors[1];
pImageData->data[colorsRead + 2] = pColors[0];
// If we have a 4 channel 32-bit image, assign one more for the alpha
if(bits == 32)
pImageData->data[colorsRead + 3] = pColors[3];
// Increase the current pixels read, decrease the amount
// of pixels left, and increase the starting index for the next pixel.
i++;
rleID--;
colorsRead += channels;
}
}
// Else, let's read in a string of the same character
else
{
// Minus the 128 ID + 1 (127) to get the color count that needs to be read
rleID -= 127;
// Read in the current color, which is the same for a while
fread(pColors, sizeof(byte) * channels, 1, pFile);
// Go and read as many pixels as are the same
while(rleID)
{
// Assign the current pixel to the current index in our pixel array
pImageData->data[colorsRead + 0] = pColors[2];
pImageData->data[colorsRead + 1] = pColors[1];
pImageData->data[colorsRead + 2] = pColors[0];
// If we have a 4 channel 32-bit image, assign one more for the alpha
if(bits == 32)
pImageData->data[colorsRead + 3] = pColors[3];
// Increase the current pixels read, decrease the amount
// of pixels left, and increase the starting index for the next pixel.
i++;
rleID--;
colorsRead += channels;
}
}
}
// Free up pColors
delete[] pColors;
}
// Close the file pointer that opened the file
fclose(pFile);
// Fill in our tImageTGA structure to pass back
pImageData->channels = channels;
pImageData->sizeX = width;
pImageData->sizeY = height;
// Return the TGA data (remember, you must free this data after you are done)
return pImageData;
}

22
api/tgalib.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef TGALIB_H
#define TGALIB_H
#include <windows.h>
#include <stdio.h>
#define TGA_RGB 2 // This tells us it's a normal RGB (really BGR) file
#define TGA_A 3 // This tells us it's a ALPHA file
#define TGA_RLE 10 // This tells us that the targa is Run-Length Encoded (RLE)
struct tImageTGA
{
int channels; // The channels in the image (3 = RGB : 4 = RGBA)
int sizeX; // The width of the image in pixels
int sizeY; // The height of the image in pixels
unsigned char *data; // The image pixel data
};
tImageTGA *LoadTGA(const char *filename);
#endif

View File

@ -20926,3 +20926,11 @@ Rom 8 Dec 2004
clientgui/
BOINCBaseView.cpp
David 8 Dec 2004
- moved bmplib and tgalib from seti_boinc to boinc/api
api/
Makefile.am
bmplib.C,h (new)
tgalib.C,h (new)

View File

@ -51,15 +51,10 @@ before getting into the source code.
<li> <a href=client_app_graphic.php>Core client/application interaction (graphics)</a>
<li> <a href=disk_management.php>Disk space management</a>
</ul>
<h2>Scheduling server</h2>
<h2>Server programs</h2>
<ul>
<li> <a href=database.php>The BOINC database</a>
<li> <a href=sched_policy.php>Policy</a>
<li> <a href=sched_impl.php>Implementation</a>
<li> <a href=sched_debug.php>Debugging</a>
</ul>
<h2>Back end</h2>
<ul>
<li> <a href=sched_policy.php>Work distribution policy</a>
<li> <a href=backend_state.php>Backend state transitions</a>
<li> <a href=backend_logic.php>The logic of backend programs</a>
<li> <a href=server_debug.php>Debugging server components</a>

View File

@ -47,6 +47,7 @@ show_name("Gilson Laurent");
show_name("Bernd Machenschalk");
show_name("Sebastian Masch");
show_name("Kenichi Miyoshi");
show_name("Kjell Nedrelid");
show_name("J.R. Oldroyd");
show_name("Jakob Pedersen");
show_name("Stephen Pellicer");

View File

@ -106,6 +106,11 @@ show_link(
"www.boinc.pl",
"http://www.boinc.pl"
);
show_link(
"Portuguese",
"Portugal@home",
"http://portugalathome.pt.vu/"
);
show_link(
"Russian",
"www.boinc.narod.ru",

View File

@ -1,25 +0,0 @@
<?php
require_once("docutil.php");
page_head("Scheduling server: debugging");
echo "
<pre>
Here's a useful technique for troubleshooting scheduler problems:
1) Copy the \"scheduler_request_X.xml\" file from a client to the
machine running the scheduler. (X = your project URL)
2) Run the scheduler under the debugger, giving it this file as stdin,
i.e.:
gdb cgi
(set a breakpoint)
r < scheduler_request_X.xml
3) You may have to doctor the database as follows:
update host set rpc_seqno=0, rpc_time=0 where hostid=N
to keep the scheduler from rejecting the request.
</pre>
";
page_tail();
?>

View File

@ -1,8 +0,0 @@
<?php
require_once("docutil.php");
page_head("Scheduling server: implementation");
echo "
<p>
";
page_tail();
?>

View File

@ -1,6 +1,6 @@
<?php
require_once("docutil.php");
page_head("Scheduling server: policy");
page_head("Work distribution policy");
echo "
<p>
The scheduling server will attempt to send enough work to exceed a

View File

@ -27,12 +27,28 @@ database-level problems.
<h2>Scheduler single-stepping</h2>
The scheduler is a CGI program.
It reads from stdin and writes to stdout,
so you can also run it with a command-line debugger like gdb.
Direct a scheduler request file
(which you can copy from a client;
they're saved in files called sched_request_PROJECT.xml)
to stdin, set breakpoints, and start stepping through the code.
<p>
so you can also run it with a command-line debugger like gdb:
<ul>
<li>
Copy the \"scheduler_request_X.xml\" file from a client to the
machine running the scheduler. (X = your project URL)
<li>
Run the scheduler under the debugger, giving it this file as stdin,
i.e.:
<pre>
gdb cgi
(set a breakpoint)
r &lt; scheduler_request_X.xml
</pre>
<li>
You may have to doctor the database as follows:
update host set rpc_seqno=0, rpc_time=0 where hostid=N
to keep the scheduler from rejecting the request.
</ul>
This is useful for figuring out why your project is generating
'no work available' messages.

View File

@ -5,16 +5,17 @@ echo "
The <code>update_versions</code> script
releases new application versions.
It makes the needed database entries and copies files
to the download directory.
It creates database entries and copies files to the download directory.
<p>
To use:
<ul>
<li> Create an 'apps directory' under the project directory.
Add an ", htmlspecialchars("<app_dir>"),
<li>
If it doesn't already exit,
create an directory 'apps' under the project directory,
and add an ", htmlspecialchars("<app_dir>"),
" element to config.xml giving the path of the apps directory.
<li> Create a subdirectory for each application,
with the same name as the application.
with the short name of the application.
Put new application versions here.
<code>update_versions</code>
scans these directories for new application versions.
@ -27,13 +28,14 @@ File names must be of the form <code>NAME_VERSION_PLATFORM[.ext]</code>, e.g.:
boinc_3.17_i686-pc-linux-gnu.gz
astropulse_7.17_windows_intelx86.exe
</pre>
The prefix name and extensions .gz, .exe, .sig are ignored.
<p>
Important notes:
<ul>
<li> <b>Platform strings must match the names of platforms in the database.</b>
<li>
<b>Platform strings must match the names of platforms in the database.</b>
If needed, <a href=tool_xadd.php>add the platform to the DB</a>.
<li> <b>Your application must have the same major version number
<li>
<b>Applications must have the same major version number
as your BOINC server software</b>.
</ul>
@ -48,6 +50,14 @@ Recommended code-signing practices are described
<a href=code_signing.php>here</a>.
<p>
If a file of the form
<pre>
EXEC_FILENAME.file_ref_info
</pre>
is found, its contents will be added to the &lt;file_info>
element describing the file
(you can use this for attributes like &lt;copy_file>).
<h3>Min/max core version</h3>
Application versions have fields <code>min_core_version</code>
and <code>max_core_version</code> which, if nonzero,
@ -55,7 +65,7 @@ indicates the range of core client version numbers
to which the application version should be sent.
Update_versions, by default, sets this to the largest
core client version number in the database.
To change this, you can manually edit the app_version record.
To change this, you can manually update the app_version record.
<h3>Multiple-file application versions</h3>