1

I've been working on Resize for a few weeks now and just can't seem to get the vertical replication working. I have to apologise in advance, my code is a mess, has a number of replicated notes, and is probably not a particularly intuitive/effective design.

After several dead-ends, I decided to use a system that reads the relevant triples, duplicates them x times (x being the scale), adds padding, and reverts the infile back to the start of the row. It runs this process (x - 1) times. The program then runs similar code for the final replication of the row, adds the padding, but instead skips forward over the infile padding. Long story short, it doesn't work and creates appropriately-sized images with a few correct rows (not always) and large black bars.

The relevant portion of the code is below.

for (int i = 0, biHeight = abs(old_height); i < biHeight; i++)
    {
        for (int a = 0; a < (scale - 1); a++)
        {
            // iterate over pixels in scanline
            for (int j = 0; j < old_width; j++)
            {
                // temporary storage
                RGBTRIPLE triple;

                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

                // write RGB triple to outfile
                for (int b = 0; b < scale; b++)
                {
                    fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
                }
            }

            // add output file padding, if any
            for (int k = 0; k < new_padding; k++)
            {
                fputc(0x00, outptr);
            }

            fseek(inptr, -(old_width), SEEK_CUR);
        }

        // iterate over pixels in scanline
        for (int j = 0; j < old_width; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

            // read RGB triple from infile
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

            // write RGB triple to outfile
            for (int b = 0; b < scale; b++)
            {
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

        // skip over input file padding, if any
        fseek(inptr, old_padding, SEEK_CUR);

        for (int k = 0; k < new_padding; k++)
        {
            fputc(0x00, outptr);
        }

    }

If anyone could point out to my where I'm going wrong I would be extremely grateful!

1

You are very close to getting the answer, but I see a minor issue that is messing up your solution.

While your idea is right about using fseek to move the cursor back repeat the line scale - 1 times, you need to multiply your old_width by sizeof(RGBTRIPLE). I am pretty sure this is because fseek works in bytes and not in pixels, so that each pixel is three bytes and therefore you are only moving back 1/3 of the way you need the cursor to go. I remember seeing a lot of posts about this issue before, but now I can't find them, but I'm sure you can if you want to make sure that I am correct. However, this will probably result in a new problem of clang not liking an it being an unsigned integer, or that of integer overflow itself, of which there are a few solutions to. One it just to make a long variable outside the loop with the amount that you want to offset and that should work, or you can try these solutions (which also explain quite nicely why the problem comes up in the first place) here:

Error in my pset4 resize.c code

pset4 resize.c negation of 12 cannot be represented in type unsigned long

Now I thought was another problem in that you messed up the order of fseek to skip the old_padding with adding the new_padding at the end of your for loop (or else wouldn't you be putting padding at the start of the next line?), but when I tried it out myself it seemed to work either way. I'm sort of confused about that, unless perhaps fputc behaves differently than I thought, maybe you know why?

In any event good job getting to this point as it is, this has been the hardest problem for me so far, and it alone was harder than most of the other psets for me! Feel free to ask any questions to clarify below, I am very new at this myself.

2
  • Thanks for the help! I followed your first point and, strangely enough, the whole thing seems to be working perfectly. I will take a look into your other points as I'm sure there'll be an error somewhere! I'm a little confused about the function of fputc (even after reading the description) and padding in general now. I figured I needed to use old_padding in fseek to avoid duplicating them, and then new_padding to apply the padding to the outfile with fputc (and thus put the cursor in the appropriate place for the next line). Is that not correct?
    – Syates29
    Jun 28 '17 at 16:57
  • @Syates29 Oh, I for some reason thought that when you added padding in the second time you were using the old_padding not the new_padding. You are right then, there was only that one problem at least that I could see, so much the better! And indeed now that I think about it more, it shouldn't matter which order you fseek or put the out_padding because fputc is moving the cursor on the outfile not the infile which is being moved with fseek. I think you know how fputc works and the padding, but I just confused you unnecessarily. I'll edit my answer now. Jun 28 '17 at 19:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .