int main(int argc, char* argv[]) { if(argc != 2) { printUsage(argv[0]); return 1; } std::string host_address; int num_of_threads; int timeout; int zmq_port; int boost_port; readConfig(argv[1], host_address, num_of_threads, timeout, zmq_port, boost_port); Reactor::getInstance().setTimeoutForHandles(timeout); PEventHandler zmqEventHandler = PEventHandler(new EventHandlerZmq()); PHandle handleZmq = PHandle(new HandleZmq(host_address, zmq_port)); handleZmq->addEventHandler(zmqEventHandler); Reactor::getInstance().registerHandle(handleZmq); #ifdef __unix__ PEventHandler boostEventHandler = PEventHandler(new EventHandlerBoost()); PHandle handleBoost = PHandle(new HandleBoost(boost_port)); handleBoost->addEventHandler(boostEventHandler); Reactor::getInstance().registerHandle(handleBoost); #endif ThreadManager threadManager(num_of_threads); threadManager.run(); return 0; }
s32 pngDecClose(PPUThread& ppu, PHandle handle, PStream stream) { // Remove the file descriptor, if a file descriptor was used for decoding if (stream->buffer->file) { idm::remove<lv2_file_t>(stream->buffer->fd); } // Deallocate the PNG buffer structure used to decode from memory, if we decoded from memory if (stream->buffer) { if (handle->free(ppu, stream->buffer, handle->free_arg) != 0) { cellPngDec.error("PNG buffer decoding structure deallocation failed."); return CELL_PNGDEC_ERROR_FATAL; } } // Free the memory allocated by libpng png_destroy_read_struct(&stream->png_ptr, &stream->info_ptr, nullptr); // Deallocate the stream memory if (handle->free(ppu, stream, handle->free_arg) != 0) { cellPngDec.error("PNG stream deallocation failed."); return CELL_PNGDEC_ERROR_FATAL; } return CELL_OK; }
LUA_API void lua_pushpropertypage (lua_State *L, PropertyPage *pPage) { LPropertyPage *plPage = dynamic_cast<LPropertyPage *>(pPage); if (plPage) ++plPage->m_nRefCount; PHandle *phPanel = (PHandle *)lua_newuserdata(L, sizeof(PHandle)); phPanel->Set(pPage); luaL_getmetatable(L, "PropertyPage"); lua_setmetatable(L, -2); }
s32 pngDecDestroy(PPUThread& ppu, PHandle handle) { // Deallocate the decoder handle memory if (handle->free(ppu, handle, handle->free_arg) != 0) { cellPngDec.error("PNG decoder deallocation failed."); return CELL_PNGDEC_ERROR_FATAL; } return CELL_OK; }
s32 pngDecOpen(PPUThread& ppu, PHandle handle, PPStream png_stream, PSrc source, POpenInfo open_info, PCbControlStream control_stream = vm::null, POpenParam open_param = vm::null) { // Check if partial image decoding is used if (control_stream || open_param) { throw EXCEPTION("Partial image decoding is not supported."); } // Allocate memory for the stream structure auto stream = vm::ptr<PngStream>::make(handle->malloc(ppu, sizeof(PngStream), handle->malloc_arg).addr()); // Check if the allocation of memory for the stream structure failed if (!stream) { cellPngDec.error("PNG stream creation failed."); return CELL_PNGDEC_ERROR_FATAL; } // Set memory info open_info->initSpaceAllocated = sizeof(PngStream); // Set the stream source to the source give by the game stream->source = *source; // Indicate that a fixed alpha value isn't used, if not specified otherwise stream->fixed_alpha = false; // Use virtual memory address as a handle *png_stream = stream; // Allocate memory for the PNG buffer for decoding auto buffer = vm::ptr<PngBuffer>::make(handle->malloc(ppu, sizeof(PngBuffer), handle->malloc_arg).addr()); // Check for if the buffer structure allocation failed if (!buffer) { throw EXCEPTION("Memory allocation for the PNG buffer structure failed."); } // We might not be reading from a file stream buffer->file = false; // Set the buffer pointer in the stream structure, so we can later deallocate it stream->buffer = buffer; // Open the buffer/file and check the header u8 header[8]; // Need to test it somewhere if (stream->source.fileOffset != 0) { throw EXCEPTION("Non-0 file offset not supported."); } // Depending on the source type, get the first 8 bytes if (source->srcSelect == CELL_PNGDEC_FILE) { // Open a file stream fs::file file_stream(vfs::get(stream->source.fileName.get_ptr())); // Check if opening of the PNG file failed if (!file_stream) { cellPngDec.error("Opening of PNG failed. (%s)", stream->source.fileName.get_ptr()); return CELL_PNGDEC_ERROR_OPEN_FILE; } // Read the header if (file_stream.read(header, 8) != 8) { cellPngDec.error("PNG header is too small."); return CELL_PNGDEC_ERROR_HEADER; } // Get the file descriptor buffer->fd = idm::make<lv2_file_t>(std::move(file_stream), 0, 0); // Indicate that we need to read from a file stream buffer->file = true; } else { // We can simply copy the first 8 bytes memcpy(header, stream->source.streamPtr.get_ptr(), 8); } // Check if the header indicates a valid PNG file if (png_sig_cmp(header, 0, 8)) { cellPngDec.error("PNG signature is invalid."); return CELL_PNGDEC_ERROR_HEADER; } // Create a libpng structure, also pass our custom error/warning functions stream->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, pngDecError, pngDecWarning); // Check if the creation of the structure failed if (!stream->png_ptr) { cellPngDec.error("Creation of png_structp failed."); return CELL_PNGDEC_ERROR_FATAL; } // Create a libpng info structure stream->info_ptr = png_create_info_struct(stream->png_ptr); // Check if the creation of the structure failed if (!stream->info_ptr) { throw EXCEPTION("Creation of png_infop failed."); } // Set a point to return to when an error occurs in libpng if (setjmp(png_jmpbuf(stream->png_ptr))) { throw EXCEPTION("Fatal error in libpng."); } // We must indicate, that we allocated more memory open_info->initSpaceAllocated += sizeof(PngBuffer); // Init the IO for either reading from a file or a buffer if (source->srcSelect == CELL_PNGDEC_BUFFER) { // Set the data pointer and the file size buffer->length = stream->source.fileSize; buffer->data = stream->source.streamPtr; // Since we already read the header, we start reading from position 8 buffer->cursor = 8; } // Set the custom read function for decoding png_set_read_fn(stream->png_ptr, buffer.get_ptr(), pngDecReadBuffer); // We need to tell libpng, that we already read 8 bytes png_set_sig_bytes(stream->png_ptr, 8); // Read the basic info of the PNG file png_read_info(stream->png_ptr, stream->info_ptr); // Read the header info for future use stream->info.imageWidth = png_get_image_width(stream->png_ptr, stream->info_ptr); stream->info.imageHeight = png_get_image_height(stream->png_ptr, stream->info_ptr); stream->info.numComponents = png_get_channels(stream->png_ptr, stream->info_ptr); stream->info.colorSpace = getPngDecColourType(png_get_color_type(stream->png_ptr, stream->info_ptr)); stream->info.bitDepth = png_get_bit_depth(stream->png_ptr, stream->info_ptr); stream->info.interlaceMethod = png_get_interlace_type(stream->png_ptr, stream->info_ptr); stream->info.chunkInformation = pngDecGetChunkInformation(stream); return CELL_OK; }
void ResizeWindowControls( EditablePanel *pWindow, int tall, int wide, int offsetX, int offsetY ) { if (!pWindow || !pWindow->GetBuildGroup() || !pWindow->GetBuildGroup()->GetPanelList()) return; CUtlVector<PHandle> *panelList = pWindow->GetBuildGroup()->GetPanelList(); CUtlVector<Panel *> resizedPanels; CUtlVector<Panel *> movedPanels; // Resize to account for 1.25 aspect ratio (1280x1024) screens { for ( int i = 0; i < panelList->Size(); ++i ) { PHandle handle = (*panelList)[i]; Panel *panel = handle.Get(); bool found = false; for ( int j = 0; j < resizedPanels.Size(); ++j ) { if (panel == resizedPanels[j]) found = true; } if (!panel || found) { continue; } resizedPanels.AddToTail( panel ); // don't move a panel more than once if ( panel != pWindow ) { RepositionControl( panel ); } } } // and now re-center them. Woohoo! for ( int i = 0; i < panelList->Size(); ++i ) { PHandle handle = (*panelList)[i]; Panel *panel = handle.Get(); bool found = false; for ( int j = 0; j < movedPanels.Size(); ++j ) { if (panel == movedPanels[j]) found = true; } if (!panel || found) { continue; } movedPanels.AddToTail( panel ); // don't move a panel more than once if ( panel != pWindow ) { int x, y; panel->GetPos( x, y ); panel->SetPos( x + offsetX, y + offsetY ); #if DEBUG_WINDOW_REPOSITIONING DevMsg( "Repositioning '%s' from (%d,%d) to (%d,%d) -- a distance of (%d,%d)\n", panel->GetName(), x, y, x + offsetX, y + offsetY, offsetX, offsetY ); #endif } } }
LUA_API lua_PropertyPage *lua_topropertypage (lua_State *L, int idx) { PHandle *phPanel = dynamic_cast<PHandle *>((PHandle *)lua_touserdata(L, idx)); if (phPanel == NULL) return NULL; return dynamic_cast<lua_PropertyPage *>(phPanel->Get()); }
s32 pngDecodeData(ppu_thread& ppu, PHandle handle, PStream stream, vm::ptr<u8> data, PDataControlParam data_control_param, PDataOutInfo data_out_info, PCbControlDisp cb_control_disp = vm::null, PDispParam disp_param = vm::null) { // Indicate, that the PNG decoding is stopped/failed. This is incase, we return an error code in the middle of decoding data_out_info->status = CELL_PNGDEC_DEC_STATUS_STOP; const u32 bytes_per_line = data_control_param->outputBytesPerLine; // Log this for now if (bytes_per_line < stream->out_param.outputWidthByte) { fmt::throw_exception("Bytes per line less than expected output! Got: %d, expected: %d" HERE, bytes_per_line, stream->out_param.outputWidthByte); } // partial decoding if (cb_control_disp && stream->outputCounts > 0) { // get data from cb auto streamInfo = vm::ptr<CellPngDecStrmInfo>::make(handle->malloc_(ppu, sizeof(CellPngDecStrmInfo), handle->malloc_arg).addr()); auto streamParam = vm::ptr<CellPngDecStrmParam>::make(handle->malloc_(ppu, sizeof(CellPngDecStrmParam), handle->malloc_arg).addr()); stream->cbDispInfo = vm::ptr<CellPngDecDispInfo>::make(handle->malloc_(ppu, sizeof(CellPngDecDispInfo), handle->malloc_arg).addr()); stream->cbDispParam = vm::ptr<CellPngDecDispParam>::make(handle->malloc_(ppu, sizeof(CellPngDecDispParam), handle->malloc_arg).addr()); auto freeMem = [&]() { handle->free_(ppu, streamInfo, handle->free_arg); handle->free_(ppu, streamParam, handle->free_arg); handle->free_(ppu, stream->cbDispInfo, handle->free_arg); handle->free_(ppu, stream->cbDispParam, handle->free_arg); }; // set things that won't change between callbacks stream->cbDispInfo->outputFrameWidthByte = bytes_per_line; stream->cbDispInfo->outputFrameHeight = stream->out_param.outputHeight; stream->cbDispInfo->outputWidthByte = stream->out_param.outputWidthByte; stream->cbDispInfo->outputBitDepth = stream->out_param.outputBitDepth; stream->cbDispInfo->outputComponents = stream->out_param.outputComponents; stream->cbDispInfo->outputHeight = stream->outputCounts; stream->cbDispInfo->outputStartXByte = 0; stream->cbDispInfo->outputStartY = 0; stream->cbDispInfo->scanPassCount = 0; stream->cbDispInfo->nextOutputStartY = 0; stream->ppuContext = &ppu; stream->nextRow = stream->cbDispInfo->outputHeight; stream->cbCtrlDisp.cbCtrlDispArg = cb_control_disp->cbCtrlDispArg; stream->cbCtrlDisp.cbCtrlDispFunc = cb_control_disp->cbCtrlDispFunc; stream->cbDispParam->nextOutputImage = disp_param->nextOutputImage; streamInfo->decodedStrmSize = stream->buffer->cursor; // push the rest of the buffer we have if (stream->buffer->length > stream->buffer->cursor) { u8* data = static_cast<u8*>(stream->buffer->data.get_ptr()) + stream->buffer->cursor; try { png_process_data(stream->png_ptr, stream->info_ptr, data, stream->buffer->length - stream->buffer->cursor); } catch (LibPngCustomException&) { freeMem(); return CELL_PNGDEC_ERROR_FATAL; } streamInfo->decodedStrmSize = stream->buffer->length; } // todo: commandPtr // then just loop until the end, the callbacks should take care of the rest while (stream->endOfFile != true) { stream->cbCtrlStream.cbCtrlStrmFunc(ppu, streamInfo, streamParam, stream->cbCtrlStream.cbCtrlStrmArg); streamInfo->decodedStrmSize += streamParam->strmSize; try { png_process_data(stream->png_ptr, stream->info_ptr, static_cast<u8*>(streamParam->strmPtr.get_ptr()), streamParam->strmSize); } catch (LibPngCustomException&) { freeMem(); return CELL_PNGDEC_ERROR_FATAL; } } freeMem(); } else { // Check if the image needs to be flipped const bool flip = stream->out_param.outputMode == CELL_PNGDEC_BOTTOM_TO_TOP; // Decode the image // todo: commandptr try { for (int j = 0; j < stream->passes; j++) { for (int i = 0; i < stream->out_param.outputHeight; ++i) { const u32 line = flip ? stream->out_param.outputHeight - i - 1 : i; png_read_row(stream->png_ptr, &data[line*bytes_per_line], nullptr); } } png_read_end(stream->png_ptr, stream->info_ptr); } catch (LibPngCustomException&) { return CELL_PNGDEC_ERROR_FATAL; } } // Get the number of iTXt, tEXt and zTXt chunks const s32 text_chunks = png_get_text(stream->png_ptr, stream->info_ptr, nullptr, nullptr); // Set the chunk information and the previously obtained number of text chunks data_out_info->numText = (u32)text_chunks; data_out_info->chunkInformation = pngDecGetChunkInformation(stream.get_ptr(), true); png_unknown_chunkp unknowns; const int num_unknowns = png_get_unknown_chunks(stream->png_ptr, stream->info_ptr, &unknowns); data_out_info->numUnknownChunk = num_unknowns; // Indicate that the decoding succeeded data_out_info->status = CELL_PNGDEC_DEC_STATUS_FINISH; return CELL_OK; }
s32 pngDecOpen(ppu_thread& ppu, PHandle handle, PPStream png_stream, PSrc source, POpenInfo open_info, PCbControlStream control_stream = vm::null, POpenParam open_param = vm::null) { // partial decoding only supported with buffer type if (source->srcSelect != CELL_PNGDEC_BUFFER && control_stream) { cellPngDec.error("Attempted partial image decode with file."); return CELL_PNGDEC_ERROR_STREAM_FORMAT; } // Allocate memory for the stream structure auto stream = vm::ptr<PngStream>::make(handle->malloc_(ppu, sizeof(PngStream), handle->malloc_arg).addr()); // Check if the allocation of memory for the stream structure failed if (!stream) { cellPngDec.error("PNG stream creation failed."); return CELL_PNGDEC_ERROR_FATAL; } // Set memory info open_info->initSpaceAllocated = sizeof(PngStream); // Set the stream source to the source give by the game stream->source = *source; // Use virtual memory address as a handle *png_stream = stream; // Allocate memory for the PNG buffer for decoding auto buffer = vm::ptr<PngBuffer>::make(handle->malloc_(ppu, sizeof(PngBuffer), handle->malloc_arg).addr()); // Check for if the buffer structure allocation failed if (!buffer) { fmt::throw_exception("Memory allocation for the PNG buffer structure failed." HERE); } // We might not be reading from a file stream buffer->file = false; // Set the buffer pointer in the stream structure, so we can later deallocate it stream->buffer = buffer; // Open the buffer/file and check the header u8 header[8]; // Need to test it somewhere if (stream->source.fileOffset != 0) { fmt::throw_exception("Non-0 file offset not supported." HERE); } // Depending on the source type, get the first 8 bytes if (source->srcSelect == CELL_PNGDEC_FILE) { // Open a file stream fs::file file_stream(vfs::get(stream->source.fileName.get_ptr())); // Check if opening of the PNG file failed if (!file_stream) { cellPngDec.error("Opening of PNG failed. (%s)", stream->source.fileName.get_ptr()); return CELL_PNGDEC_ERROR_OPEN_FILE; } // Read the header if (file_stream.read(header, 8) != 8) { cellPngDec.error("PNG header is too small."); return CELL_PNGDEC_ERROR_HEADER; } // Get the file descriptor buffer->fd = idm::make<lv2_fs_object, lv2_file>(stream->source.fileName.get_ptr(), std::move(file_stream), 0, 0); // Indicate that we need to read from a file stream buffer->file = true; } else { // We can simply copy the first 8 bytes memcpy(header, stream->source.streamPtr.get_ptr(), 8); } // Check if the header indicates a valid PNG file if (png_sig_cmp(header, 0, 8)) { cellPngDec.error("PNG signature is invalid."); return CELL_PNGDEC_ERROR_HEADER; } // Create a libpng structure, also pass our custom error/warning functions stream->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, pngDecError, pngDecWarning); // Check if the creation of the structure failed if (!stream->png_ptr) { cellPngDec.error("Creation of png_structp failed."); return CELL_PNGDEC_ERROR_FATAL; } // Create a libpng info structure stream->info_ptr = png_create_info_struct(stream->png_ptr); // Check if the creation of the structure failed if (!stream->info_ptr) { fmt::throw_exception("Creation of png_infop failed." HERE); } // We must indicate, that we allocated more memory open_info->initSpaceAllocated += sizeof(PngBuffer); if (source->srcSelect == CELL_PNGDEC_BUFFER) { buffer->length = stream->source.streamSize; buffer->data = stream->source.streamPtr; buffer->cursor = 8; } // Set the custom read function for decoding if (control_stream) { if (open_param && open_param->selectChunk != 0) fmt::throw_exception("Partial Decoding with selectChunk not supported yet."); stream->cbCtrlStream.cbCtrlStrmArg = control_stream->cbCtrlStrmArg; stream->cbCtrlStream.cbCtrlStrmFunc = control_stream->cbCtrlStrmFunc; png_set_progressive_read_fn(stream->png_ptr, (void *)stream.get_ptr(), pngDecInfoCallback, pngDecRowCallback, pngDecEndCallback); // push header tag to libpng to keep us in sync try { png_process_data(stream->png_ptr, stream->info_ptr, header, 8); } catch (LibPngCustomException&) { return CELL_PNGDEC_ERROR_HEADER; } } else { png_set_read_fn(stream->png_ptr, buffer.get_ptr(), pngDecReadBuffer); // We need to tell libpng, that we already read 8 bytes png_set_sig_bytes(stream->png_ptr, 8); } return CELL_OK; }