I have a simple Xcode project that contains a single C++ class. However, when I attempt to build that project in Xcode I'm getting the following error message:
error: unable to spawn process '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang' (No such file or directory) (in target 'iOSStaticLibrary' from project 'iOSStaticLibrary')
In addition, the following warning is emitted:
warning: Could not read serialized diagnostics file: error("Failed to open diagnostics file") (in target 'iOSStaticLibrary' from project 'iOSStaticLibrary')
I couldn't figure out how to attach the actual project to my post. It only consists of 3 files, so, I'm posting the relative filenames and contents below.
In order to recreate the problem, create the 3 files in the specified folder and add the corresponding content.
File ARM64/Debug/iOSStaticLibrary.xcodeproj/project.pbxproj:
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
3b051b2877334f3891e05fbf /* iOSStaticLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 810f8ddb516f4fd9aae95391 /* iOSStaticLibrary.cpp */; settings = {COMPILER_FLAGS = "-c -Wall -Wswitch -W\"no-deprecated-declarations\" -W\"empty-body\" -W\"bool-conversion\" -W\"constant-conversion\" -W\"shorten-64-to-32\" -W\"enum-conversion\" -W\"int-conversion\" -W\"return-type\" -Wparentheses -W\"no-pointer-sign\" -W\"no-format\" -Wuninitialized -W\"unreachable-code\" -W\"unused-function\" -W\"unused-value\" -W\"unused-variable\" -O0 -fno-strict-aliasing -fwritable-strings -fno-threadsafe-statics -fno-exceptions -std=gnu++11 -x c++"; }; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0e5228c6fe3a40ef9446f1d3 /* libiOSStaticLibrary.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libiOSStaticLibrary.a; sourceTree = BUILT_PRODUCTS_DIR; };
810f8ddb516f4fd9aae95391 /* iOSStaticLibrary.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = iOSStaticLibrary.cpp; path = ../../../iOSStaticLibrary.cpp; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
c8f1fdfa1a1a4cf2af0a7098 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
20adea7cddb14f79ab5df50b /* Products */ = {
isa = PBXGroup;
children = (
0e5228c6fe3a40ef9446f1d3 /* libiOSStaticLibrary.a */,
);
name = Products;
sourceTree = SOURCE_ROOT;
};
cb87a76375d04d85a8368aa7 = {
isa = PBXGroup;
children = (
810f8ddb516f4fd9aae95391 /* iOSStaticLibrary.cpp */,
20adea7cddb14f79ab5df50b /* Products */,
);
sourceTree = "\"<group>\"";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
3488e49fcf514802b7be61b6 /* iOSStaticLibrary */ = {
isa = PBXNativeTarget;
buildConfigurationList = 67256f7dc92b42baa13ec8d3 /* Build configuration list for PBXNativeTarget "iOSStaticLibrary" */;
buildPhases = (
7baf7bfde3004dd493908ddd /* Sources */,
c8f1fdfa1a1a4cf2af0a7098 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = iOSStaticLibrary;
productName = iOSStaticLibrary;
productReference = 0e5228c6fe3a40ef9446f1d3 /* libiOSStaticLibrary.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
ee73158d3505468a8fdc43b9 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = MyOrganizationName;
TargetAttributes = {
3488e49fcf514802b7be61b6 = {
CreatedOnToolsVersion = 6.1;
};
};
};
buildConfigurationList = 33fd7959eb644d189bbaa7f7 /* Build configuration list for PBXProject "iOSStaticLibrary" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
);
mainGroup = cb87a76375d04d85a8368aa7;
productRefGroup = 20adea7cddb14f79ab5df50b /* Products */;
projectDirPath = "\n\n ";
projectRoot = "\n\n ";
targets = (
3488e49fcf514802b7be61b6 /* iOSStaticLibrary */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
7baf7bfde3004dd493908ddd /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3b051b2877334f3891e05fbf /* iOSStaticLibrary.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1cbb1a8c7cbf4c2699369b65 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Debug;
};
fda96981947c4c2cb659f3e3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LIBRARY = "libc++";
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
33fd7959eb644d189bbaa7f7 /* Build configuration list for PBXProject "iOSStaticLibrary" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1cbb1a8c7cbf4c2699369b65 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
67256f7dc92b42baa13ec8d3 /* Build configuration list for PBXNativeTarget "iOSStaticLibrary" */ = {
isa = XCConfigurationList;
buildConfigurations = (
fda96981947c4c2cb659f3e3 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = ee73158d3505468a8fdc43b9 /* Project object */;
}
File iOSStaticLibrary.h
class iOSStaticLibrary
{
public:
iOSStaticLibrary();
~iOSStaticLibrary();
};
File iOSStaticLibrary.cpp:
#include "iOSStaticLibrary.h"
iOSStaticLibrary::iOSStaticLibrary()
{
}
iOSStaticLibrary::~iOSStaticLibrary()
{
}
My assumption is that something in the project.pbxproj is not as it should be. This file is generated by a code generator, not by Xcode itself so that might well be the case.
However, for the life of me I cannot figure out what's wrong.
Alright, I found the issue. The code generator creates the Xcode project as an XML file. If I open it in Xcode and apply a change to it, Xcode automatically converts the file to the other non-XML file format (i.e. as shown in the question)
Now, the code generator emits the following problematic code:
...
<key>projectDirPath</key>
<string>
</string>
...
<key>projectRoot</key>
<string>
</string>
..
Both keys (projectDirPath / projectRoot) should have an empty string as value and it actually does look like it is empty in the above XML.
However, Xcode interprets it differently. If the XML file is converted to the other format it looks as follows:
...
projectDirPath = "\n\n ";
projectRoot = "\n\n ";
...
So, Xcode interprets the whitespace between <string> and </string> as actual value. To fix it, the code generator must be adjusted to emit
...
<key>projectDirPath</key>
<string></string>
...
<key>projectRoot</key>
<string></string>
...
or <string /> or any other valid way instead of the above approach. That actually fixes the problem.
Related
I am working on a project that will require timer interrupts.
Using STM32cubeIDE, I generated code that should work with timer-interrupts. Here is a truncation of what my main.cpp looks like: (htim1 is a global handle)
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM1_Init();
HAL_TIM_Base_Start_IT(&htim1);
while(1);
Here is what MX_TIM1_INIT() looks like:
static void MX_TIM1_Init(void)
{
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 84-1;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 0xFFFF-1;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */
/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);
}
Here is what my interrupt handler looks like:
void TIM1_UP_TIM10_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */
/* USER CODE END TIM1_UP_TIM10_IRQn 0 */
// HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12); //O-SCOPE DEBUG on PA6
// if (timer1 == nullptr) return;
//timer1->TimerISR();
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */
/* USER CODE END TIM1_UP_TIM10_IRQn 1 */
}
And here is my callback function:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12); //O-SCOPE DEBUG on PA6
}
No matter what I do I can't get the debugger to even enter the handler.... Could anyone enlighten me as to what I am doing wrong? Thanks!
I would never use HAL library to set up the timers. It makes no sense for me. In the example below I will omit clock (in my case 168MHz) & GPIO settings. As you did not state what model of STM32F4 you use, this code was tested using STM32F446RET uC. Other STM32F4 have identical timers.
Setting the timer:
__HAL_RCC_TIM1_CLK_ENABLE();
TIM1 -> PSC = (20000 - 1);
TIM1 -> ARR = (4200 - 1);
//168e6 / (20000 * 4200) = 2 - two interrupts per second
TIM1 -> EGR |= TIM_EGR_UG; // reinitialize the counter and reload registers
TIM1 -> DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
TIM1 -> CR1 = TIM_CR1_CEN;
The interrupt handler. If you program in C++ handlers have to be declared as extern "C" !!!
//if you compile as C++ you need to declare handlers as "normal" C functions
//#ifdef`s are not needed if this code will never be compiled as C progream
#ifdef __cplusplus
extern "C" {
#endif
void TIM1_UP_TIM10_IRQHandler(void)
{
if(TIM1 -> SR & TIM_SR_UIF)
{
TIM1 -> SR = ~(TIM_SR_UIF); // clear UIF flag
GPIOA -> ODR ^= 1 << 5; // toggle PA5
}
}
#ifdef __cplusplus
}
#endif
And my LED connected to PA5 changes the state every 500ms.
Job done - isn't it easier than HAL?
I am trying to interface with winbond external flash memory using QSPI interface : https://www.winbond.com/resource-files/w25m02gv%20revb%20070115.pdf. I am sending read Device ID command and I expect to see something like that: Read device ID waveforms
I have connected Logic analyzer and I can see that I am sending the required command but I am not getting any answer on D1 line:
enter image description here
The code that I am trying to
void QSPI_read_ID(QSPI_HandleTypeDef *hqspi){
QSPI_CommandTypeDef sCommand;
uint32_t tmp;
int len;
/* READ ID ------------------------------------------ */
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
sCommand.Instruction = JEDEC_ID_CMD;
sCommand.AddressMode = QSPI_ADDRESS_NONE;
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = QSPI_DATA_NONE;
sCommand.DummyCycles = 8;
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
QSPI_Flash_Error_Handler(hqspi);
}
If I change the dummy cycle number from 8 to lets say 24, I am able to read first 2 bytes of the device ID:
enter image description here
I am not sure whether I am not understanding this properly. I was under the impression that if I send the read device ID command I should invoke the D1 line to send me the ID automatically. The problem that it wont let me use more than 32 dummy cycles.
Try to set recieved size as 3 and apply recieve function
void QSPI_read_ID(QSPI_HandleTypeDef *hqspi){
QSPI_CommandTypeDef sCommand;
uint8_t tmp[3];
int len;
/* READ ID ------------------------------------------ */
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
sCommand.Instruction = JEDEC_ID_CMD;
sCommand.AddressMode = QSPI_ADDRESS_NONE;
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = QSPI_DATA_NONE;
sCommand.DummyCycles = 8;
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
sCommand.NbData = 3;
if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
QSPI_Flash_Error_Handler(hqspi);
}
if (HAL_QSPI_Receive(hqspi, tmp , HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK){
QSPI_Flash_Error_Handler(hqspi);
}
}
Yes that works! I did not realise that I have to call the receive function to get the bytes ( Totally makes sense now ). Thanks.
Code here if anyone is struggling with the same problem:
void QSPI_read_ID(QSPI_HandleTypeDef *hqspi){
QSPI_CommandTypeDef sCommand;
uint8_t reg[3]; // N25Q128A13EF840E 0xEF, 0xAB, 0x21
/* READ ID ------------------------------------------ */
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
sCommand.Instruction = JEDEC_ID_CMD;
sCommand.AddressMode = QSPI_ADDRESS_NONE;
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
//sCommand.DataMode = QSPI_DATA_NONE;
sCommand.DataMode = QSPI_DATA_1_LINE;
sCommand.NbData = sizeof(reg);
sCommand.DummyCycles = 8;
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
if (HAL_QSPI_Command(hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
QSPI_Flash_Error_Handler(hqspi);
}
memset(reg, 0, sizeof(reg));
if (HAL_QSPI_Receive(hqspi, ®[0], HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
puts('ERROR:HAL_QSPI_Receive');
Error_Handler();
}
HAL_Delay(10);
}
I have a c++ code which has been connected to a visual basic user interface by someone else. Here is one of the functions code that connects c++ to visual basic:
extern "C" void PASCAL EXPORT RCS( stAct* act,stResourceDirectory* resDir, stCalendar* calendar, short numOfAct, short numOfRes, short numOfCal, int nDataDate )
{
Network network;
short id;
Activity* p_act;
node<Activity>* p_node;
// Setting
network.create_calendars (calendar, numOfCal);
network.set_data_date (nDataDate);
set_activity(network, act, numOfAct );
// only for id, duration, and description
set_resource(network, act, resDir, numOfAct, numOfRes);
// create resource profile and add required resource for every activity
network.CPM ();
p_node = network.get_network_head_p();
while (p_node != NULL ) {
p_act = p_node->refer_data();
id = p_act->get_ID ();
act[id].TF_in_CPM = p_act->get_TF_min ();
act[id].FF_in_CPM = p_act->get_FF();
act[id].EST_in_CPM = p_act->get_EST ();
act[id].EFT_in_CPM = p_act->get_EFT ();
act[id].LST_in_CPM = p_act->get_LST ();
act[id].LFT_in_CPM = p_act->get_LFT ();
p_node = p_node->get_link();
}
network.RCS();
p_node = network.get_network_head_p();
while (p_node != NULL ) {
p_act = p_node->refer_data();
id = p_act->get_ID ();
act[id].TF_in_RCS = p_act->get_TF_min ();
act[id].FF_in_RCS = p_act->get_FF();
act[id].EST_in_RCS = p_act->get_EST ();
act[id].EFT_in_RCS = p_act->get_EFT ();
act[id].LST_in_RCS = p_act->get_LST ();
act[id].LFT_in_RCS = p_act->get_LFT ();
p_node = p_node->get_link();
}
}
I want to replace the visual basic part with a Java GUI and it seems confusing for me to write the connection code. Is there anyone who can help me call three c++ functions with passing arguments to the native method and receiving results from it, by JNA/ SWIG/ Runtime or any other methods you think it would work easier and better?
Here is an instructional example to help get you started. In this snippet, Java2Win64 is the DLL that contains the native code to execute. Function functionMaryam() takes 1 param as int and returns an int. Easy to expand for any data type.
public class JnaExampleMaryam {
// ------------------------------------------
// Java2Win.class
// ------------------------------------------
public interface Java2Win extends Library {
Java2Win call = (Java2Win) Native.loadLibrary("Java2Win64", Java2Win.class);
int functionMaryam(int i);
}
// ------------------------------------------
// ------------------------------------------
// Test
// ------------------------------------------
public static void main(final String args[]) throws Exception {
final File file = new File("rootToDLL", "Java2Win64.dll");
LibraryLoader.loadLibrary(file);
int result = Java2Win.call.functionMaryam(42);
}
// ------------------------------------------
See bottom for updates
I am running into a number of odd problems. For starters, I'm using the latest Eclipse CDT and before implementing do_rot_180, the compiler linked the folder projectName/include but after it now requires specific include/*.h specified below.
Related to that issue, in the project explorer, it seems to think libjpeg.h is missing or invalid despite it being in the folder on the disk.
I am working with libjpeg-9.
Includes (included what transupp.c and example.c included):
Functions (do_rot_180 is from transupp.c and read_JPEG_file is from example.c):
See updated code block below under Edit 2 (pretty much just jpegtran.c code)
This is the rotate function which is unused in jpegtran.c:
//LOCAL(void)
//do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
// JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
// jvirt_barray_ptr *src_coef_arrays,
// jvirt_barray_ptr *dst_coef_arrays)
///* 180 degree rotation is equivalent to
// * 1. Vertical mirroring;
// * 2. Horizontal mirroring.
// * These two steps are merged into a single processing routine.
// */
//{
// JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
// JDIMENSION x_crop_blocks, y_crop_blocks;
// int ci, i, j, offset_y;
// JBLOCKARRAY src_buffer, dst_buffer;
// JBLOCKROW src_row_ptr, dst_row_ptr;
// JCOEFPTR src_ptr, dst_ptr;
// jpeg_component_info *compptr;
//
// MCU_cols = srcinfo->output_width /
// (dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
// MCU_rows = srcinfo->output_height /
// (dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
//
// for (ci = 0; ci < dstinfo->num_components; ci++) {
// compptr = dstinfo->comp_info + ci;
// comp_width = MCU_cols * compptr->h_samp_factor;
// comp_height = MCU_rows * compptr->v_samp_factor;
// x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
// y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
// for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
// dst_blk_y += compptr->v_samp_factor) {
// dst_buffer = (*srcinfo->mem->access_virt_barray)
// ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
// (JDIMENSION) compptr->v_samp_factor, TRUE);
// if (y_crop_blocks + dst_blk_y < comp_height) {
// /* Row is within the vertically mirrorable area. */
// src_buffer = (*srcinfo->mem->access_virt_barray)
// ((j_common_ptr) srcinfo, src_coef_arrays[ci],
// comp_height - y_crop_blocks - dst_blk_y -
// (JDIMENSION) compptr->v_samp_factor,
// (JDIMENSION) compptr->v_samp_factor, FALSE);
// } else {
// /* Bottom-edge rows are only mirrored horizontally. */
// src_buffer = (*srcinfo->mem->access_virt_barray)
// ((j_common_ptr) srcinfo, src_coef_arrays[ci],
// dst_blk_y + y_crop_blocks,
// (JDIMENSION) compptr->v_samp_factor, FALSE);
// }
// for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
// dst_row_ptr = dst_buffer[offset_y];
// if (y_crop_blocks + dst_blk_y < comp_height) {
// /* Row is within the mirrorable area. */
// src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
// for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
// dst_ptr = dst_row_ptr[dst_blk_x];
// if (x_crop_blocks + dst_blk_x < comp_width) {
// /* Process the blocks that can be mirrored both ways. */
// src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
// for (i = 0; i < DCTSIZE; i += 2) {
// /* For even row, negate every odd column. */
// for (j = 0; j < DCTSIZE; j += 2) {
// *dst_ptr++ = *src_ptr++;
// *dst_ptr++ = - *src_ptr++;
// }
// /* For odd row, negate every even column. */
// for (j = 0; j < DCTSIZE; j += 2) {
// *dst_ptr++ = - *src_ptr++;
// *dst_ptr++ = *src_ptr++;
// }
// }
// } else {
// /* Any remaining right-edge blocks are only mirrored vertically. */
// src_ptr = src_row_ptr[x_crop_blocks + dst_blk_x];
// for (i = 0; i < DCTSIZE; i += 2) {
// for (j = 0; j < DCTSIZE; j++)
// *dst_ptr++ = *src_ptr++;
// for (j = 0; j < DCTSIZE; j++)
// *dst_ptr++ = - *src_ptr++;
// }
// }
// }
// } else {
// /* Remaining rows are just mirrored horizontally. */
// src_row_ptr = src_buffer[offset_y];
// for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
// if (x_crop_blocks + dst_blk_x < comp_width) {
// /* Process the blocks that can be mirrored. */
// dst_ptr = dst_row_ptr[dst_blk_x];
// src_ptr = src_row_ptr[comp_width - x_crop_blocks - dst_blk_x - 1];
// for (i = 0; i < DCTSIZE2; i += 2) {
// *dst_ptr++ = *src_ptr++;
// *dst_ptr++ = - *src_ptr++;
// }
// } else {
// /* Any remaining right-edge blocks are only copied. */
// jcopy_block_row(src_row_ptr + dst_blk_x + x_crop_blocks,
// dst_row_ptr + dst_blk_x,
// (JDIMENSION) 1);
// }
// }
// }
// }
// }
// }
//}
On top of that, I can't actually find where jcopy_block_row is defined. I've looked through all of the include files and their .c counterparts.
I commented out the error handling stuff in the read_JPEG_file function and want to call do_rot_180 from within but I haven't gotten that far yet.
The only clue I've found is this in transupp.c:
Additional note: jpegtran.exe works separately with the compiled .DLL so it's got to be somewhere.
Edit - copied jpegint.h over into include/ which resolved the include issues.
#ifdef JPEG_INTERNALS
#include "jpegint.h" /* fetch private declarations */
#include "jerror.h" /* fetch error codes too */
#endif
Now it's unable to compile even though they all seem to be declared in jpeglib.h or jpegint.h:
Edit 2 - code now contains jpegtran.c stuff for just being able to rotate 180 degrees. Updated code block:
/*********************************************************************************/
/* Defines */
/*********************************************************************************/
#define JPEG_INTERNALS
/*********************************************************************************/
/* Includes */
/*********************************************************************************/
#include <stdio.h>
#include <iostream>
#include "jinclude.h"
#include "jpeglib.h"
#include "cdjpeg.h"
#include "transupp.h"
#include "jerror.h"
#include <ctype.h>
#include <setjmp.h>
//using namespace std;
static char * infilename;
static char * outfilename;
static JCOPY_OPTION copyoption;
static jpeg_transform_info transformoption;
FILE * infile;
FILE * outfile;
void openFile(char file) {
if(file == 'i') {
infile = fopen(infilename, "rb");
}
else if(file == 'o') {
outfile = fopen(outfilename, "wb");
}
}
/*********************************************************************************/
/* Main Execution Block */
/*********************************************************************************/
int main() {
struct jpeg_decompress_struct srcinfo;
struct jpeg_compress_struct dstinfo;
struct jpeg_error_mgr jsrcerr, jdsterr;
jvirt_barray_ptr * src_coef_arrays;
jvirt_barray_ptr * dst_coef_arrays;
//int file_index;
srcinfo.err = jpeg_std_error(&jsrcerr);
jpeg_create_decompress(&srcinfo);
dstinfo.err = jpeg_std_error(&jdsterr);
jpeg_create_compress(&dstinfo);
jsrcerr.trace_level = jdsterr.trace_level;
srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use;
//
outfilename = NULL;
copyoption = JCOPYOPT_DEFAULT;
transformoption.transform = JXFORM_NONE;
transformoption.trim = FALSE;
transformoption.force_grayscale = FALSE;
transformoption.transform = JXFORM_ROT_180;
//
std::cout << "Enter a filename to rotate 180 degrees." << std::endl;
std::cin >> infilename;
openFile('i');
std::cout << "Enter the output filename." << std::endl;
std::cin >> outfilename;
openFile('o');
//
jpeg_stdio_src(&srcinfo, infile);
jcopy_markers_setup(&srcinfo, copyoption);
(void) jpeg_read_header(&srcinfo, TRUE);
jtransform_request_workspace(&srcinfo, &transformoption);
src_coef_arrays = jpeg_read_coefficients(&srcinfo);
jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo,
src_coef_arrays,
&transformoption);
jpeg_stdio_dest(&dstinfo, outfile);
jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);
jtransform_execute_transformation(&srcinfo, &dstinfo,
src_coef_arrays,
&transformoption);
jpeg_finish_compress(&dstinfo);
jpeg_destroy_compress(&dstinfo);
(void) jpeg_finish_decompress(&srcinfo);
jpeg_destroy_decompress(&srcinfo);
//
if (infile != stdin)
fclose(infile);
if (outfile != stdout)
fclose(outfile);
return 0;
}
/*********************************************************************************/
/* End of Program */
/*********************************************************************************/
Edit 3 - Made the changes Jeff mentioned and I am running into this problem when compiling it (in Eclipse):
cannot find -lC:\Users\tmp\workspace2\jpegManipulator\lib\libjpeg.a jpegManipulator C/C++ Problem
Invalid project path: Duplicate path entries found (/jpegManipulator [Include path] base-path:jpegManipulator isSystemInclude:true includePath:include), path: [/jpegManipulator].jpegManipulator pathentry Path Entry Problem
I have workspace directory /lib set as library source and also the specific libjpeg.a library set in the libraries tab - It is definitely in the directory.
If I don't include the specific libjpeg.a file, it complains about missing function references but if I do include it, it complains saying that there is no libjpeg.a to be found. This is for both v9 and v6b.
cannot find -lC:\Users\tmp\workspace2\jpeg6bmanip\libs\libjpeg.a jpeg6bmanip C/C++ Problem
cannot find -lC:\Users\tmp\workspace2\jpeg6bmanip\libs\libjpeg.la jpeg6bmanip C/C++ Problem
Solution to Edit 3 problem: https://stackoverflow.com/q/14692302/1666510 but new problem after that. Can't run the program or debug it because it claims it cannot find jpeglib.h.
I had something similar happen when developing with MinGW a couple of years ago. I had to download the source for libjpeg and build it on my machine in order to get the libjpeg.a file. The source can be found here:
http://www.ijg.org/
The problem that I found when I built this library was that when I executed 'nm libjpeg.a' it became clear that the symbols in cdjpeg.h and transupp.h were not being compiled into the library. I couldn't find a way to do it via configure since I didn't see anything obvious when I did 'configure --help'. Instead I edited the Makefile.in file where it defines the am__objects_1 list of .lo files. I added cdjpeg and transupp at the end like this:
am__objects_1 = jaricom.lo jcapimin.lo jcapistd.lo jcarith.lo \
jccoefct.lo jccolor.lo jcdctmgr.lo jchuff.lo jcinit.lo \
jcmainct.lo jcmarker.lo jcmaster.lo jcomapi.lo jcparam.lo \
jcprepct.lo jcsample.lo jctrans.lo jdapimin.lo jdapistd.lo \
jdarith.lo jdatadst.lo jdatasrc.lo jdcoefct.lo jdcolor.lo \
jddctmgr.lo jdhuff.lo jdinput.lo jdmainct.lo jdmarker.lo \
jdmaster.lo jdmerge.lo jdpostct.lo jdsample.lo jdtrans.lo \
jerror.lo jfdctflt.lo jfdctfst.lo jfdctint.lo jidctflt.lo \
jidctfst.lo jidctint.lo jquant1.lo jquant2.lo jutils.lo \
jmemmgr.lo cdjpeg.lo transupp.lo #MEMORYMGR#.lo
Then I did a 'make' and a 'make install' and the symbols were present in the library. At that point I was able to get your code to build. An autotools expert may be able to come up with a better way to do it but this will at least get you going.
it seems I am unable to find any source telling me how to use lists with libconfig.
Let's say my config file looks like this:
Layer1 = {
Layer2 = {
SomeOption = "MyValue";
Options = (
{
Option = "Full Screen";
Value = "No";
},
{
Option = "Title";
Value = "Test";
}
);
};
};
How can I read Options with libconfig++ ? I can only find methods for reading single values.
OK, I have found the answer:
using namespace libconfig;
// ...
Config *pConfig = new Config();
// ...
Setting& settings = pConfig->lookup("Layer1.Layer2.Options");
const char* op0 = settings[0]["Option"];
// ...